Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion docs/build/reference/zc-conformance.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
title: "/Zc (Conformance)"
description: "The /Zc conformance compiler options enable or disable support for conforming or backward-compatible behavior."
ms.date: 01/23/2021
ms.date: 08/12/2021
helpviewer_keywords: ["/Zc compiler options [C++]", "-Zc compiler options [C++]", "Conformance compiler options", "Zc compiler options [C++]"]
---
# `/Zc` (Conformance)
Expand Down Expand Up @@ -30,6 +30,7 @@ Here are the **`/Zc`** compiler options:
| [`/Zc:hiddenFriend`](zc-hiddenfriend.md) | Enforce Standard C++ hidden friend rules (implied by **`/permissive-`**) |
| [`/Zc:implicitNoexcept`](zc-implicitnoexcept-implicit-exception-specifiers.md) | Enable implicit **`noexcept`** on required functions (on by default). |
| [`/Zc:inline`](zc-inline-remove-unreferenced-comdat.md) | Remove unreferenced functions or data if they're COMDAT or have internal linkage only (off by default). |
| [`/Zc:lambda`](zc-lambda.md) | Enable new lambda processor for conformance-mode syntactic checks in generic lambdas. |
| [`/Zc:noexceptTypes`](zc-noexcepttypes.md) | Enforce C++17 **`noexcept`** rules (on by default in C++17 or later). |
| [`/Zc:preprocessor`](zc-preprocessor.md) | Use the new conforming preprocessor (off by default, except in C11/C17). |
| [`/Zc:referenceBinding`](zc-referencebinding-enforce-reference-binding-rules.md) | A UDT temporary won't bind to a non-const lvalue reference (off by default). |
Expand Down
39 changes: 20 additions & 19 deletions docs/build/reference/zc-cplusplus.md
Original file line number Diff line number Diff line change
@@ -1,46 +1,47 @@
---
description: "Learn more about: /Zc:__cplusplus (Enable updated __cplusplus macro)"
title: "/Zc:__cplusplus (Enable updated __cplusplus macro)"
ms.date: "05/16/2019"
ms.date: 08/11/2021
f1_keywords: ["/Zc:__cplusplus"]
helpviewer_keywords: ["-Zc:__cplusplus compiler option (C++)", "__cplusplus macro (C++)"]
---
# /Zc:__cplusplus (Enable updated __cplusplus macro)
# `/Zc:__cplusplus` (Enable updated `__cplusplus` macro)

The **/Zc:__cplusplus** compiler option enables the **\_\_cplusplus** preprocessor macro to report an updated value for recent C++ language standards support. By default, Visual Studio always returns the value "199711L" for the **\_\_cplusplus** preprocessor macro.
The **`/Zc:__cplusplus`** compiler option enables the `__cplusplus` preprocessor macro to report an updated value for recent C++ language standards support. By default, Visual Studio always returns the value `199711L` for the `__cplusplus` preprocessor macro.

## Syntax

> **/Zc:__cplusplus**[**-**]
> **`/Zc:__cplusplus`**[**`-`**]

## Remarks

The **\_\_cplusplus** preprocessor macro is commonly used to report support for a particular version of the C++ standard. Because lots of existing code appears to depend on the value of this macro matching "199711L", the compiler does not change the value of the macro unless you explicitly opt-in by using the **/Zc:__cplusplus** compiler option. The **/Zc:__cplusplus** option is available starting in Visual Studio 2017 version 15.7, and is off by default. In earlier versions of Visual Studio, and by default, or if **/Zc:__cplusplus-** is specified, Visual Studio returns the value "199711L" for the **\_\_cplusplus** preprocessor macro. The [/permissive-](permissive-standards-conformance.md) option does not enable **/Zc:__cplusplus**.
The `__cplusplus` preprocessor macro is commonly used to report support for a particular version of the C++ standard. Because a lot of existing code appears to depend on the value of this macro matching `199711L`, the compiler doesn't change the value of the macro unless you explicitly opt in by using the **`/Zc:__cplusplus`** compiler option. The **`/Zc:__cplusplus`** option is available starting in Visual Studio 2017 version 15.7, and is off by default. In earlier versions of Visual Studio, and by default, or if **`/Zc:__cplusplus-`** is specified, Visual Studio returns the value `199711L` for the `__cplusplus` preprocessor macro. The [`/permissive-`](permissive-standards-conformance.md) option doesn't enable **`/Zc:__cplusplus`**.

When the **/Zc:__cplusplus** option is enabled, the value reported by the **\_\_cplusplus** macro depends on the [/std](std-specify-language-standard-version.md) version switch setting. This table shows the possible values for the macro:
When the **`/Zc:__cplusplus`** option is enabled, the value reported by the `__cplusplus` macro depends on the [`/std`](std-specify-language-standard-version.md) version option setting. This table shows the possible values for the macro:

|/Zc:__cplusplus switch|/std:c++ switch|__cplusplus value|
|-|-|-|
Zc:__cplusplus|/std:c++14 (default)|201402L
Zc:__cplusplus|/std:c++17|201703L
Zc:__cplusplus|/std:c++latest|201704L
Zc:__cplusplus- (disabled)|Any value|199711L
Not specified|Any value|199711L
| `/Zc:__cplusplus` option | `/std` option | `__cplusplus` value |
|--|--|--|
| `Zc:__cplusplus` | `/std:c++14` (default) | `201402L` |
| `Zc:__cplusplus` | `/std:c++17` | `201703L` |
| `Zc:__cplusplus` | `/std:c++20` | `202002L` |
| `Zc:__cplusplus` | `/std:c++latest` | see text |
| `Zc:__cplusplus-` (disabled) | Any value | `199711L` |
| Not specified | Any value | `199711L` |

The compiler does not support standards switches for C++98, C++03, or C++11.
The compiler doesn't support standards options for C++98, C++03, or C++11. The **`/std:c++20`** option is available starting in Visual Studio 2019 version 16.11. The value of `__cplusplus` with the **`/std:c++latest`** option depends on the version of Visual Studio. It's always at least one higher than the highest supported `__cplusplus` standard value supported by your version of Visual Studio.

For finer-grained detection of changes to the compiler toolset, use the [_MSC_VER](../../preprocessor/predefined-macros.md) predefined macro. The value of this built-in macro is incremented for every toolset update in Visual Studio 2017 and later versions. The [_MSVC_LANG](../../preprocessor/predefined-macros.md) predefined macro reports the standard version whether the **/Zc:__cplusplus** option is enabled or disabled. When **/Zc:__cplusplus** is enabled, `__cplusplus == _MSVC_LANG`.
For finer-grained detection of changes to the compiler toolset, use the [`_MSC_VER`](../../preprocessor/predefined-macros.md) predefined macro. The value of this built-in macro is incremented for every toolset update in Visual Studio 2017 and later versions. The [`_MSVC_LANG`](../../preprocessor/predefined-macros.md) predefined macro reports the standard version whether the **`/Zc:__cplusplus`** option is enabled or disabled. When **`/Zc:__cplusplus`** is enabled, `__cplusplus` has the same value as `_MSVC_LANG`.

### To set this compiler option in Visual Studio

1. Open the project's **Property Pages** dialog box. For details, see [Set C++ compiler and build properties in Visual Studio](../working-with-project-properties.md).

1. Select the **Configuration Properties** > **C/C++** > **Command Line** property page.

1. Add **/Zc:__cplusplus** or **/Zc:__cplusplus-** to the **Additional options:** pane.
1. Add **`/Zc:__cplusplus`** or **`/Zc:__cplusplus-`** to the **Additional options:** pane.

## See also

- [/Zc (Conformance)](zc-conformance.md)
- [/std (Specify language standard version)](std-specify-language-standard-version.md)
- [Predefined macros](../../preprocessor/predefined-macros.md)
[`/Zc` (Conformance)](zc-conformance.md)\
[`/std` (Specify language standard version)](std-specify-language-standard-version.md)\
[Predefined macros](../../preprocessor/predefined-macros.md)
70 changes: 70 additions & 0 deletions docs/build/reference/zc-lambda.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
---
description: "Learn more about: /Zc:lambda (Enable updated lambda processor)"
title: "/Zc:lambda (Enable updated lambda processor)"
ms.date: 08/11/2021
f1_keywords: ["/Zc:lambda"]
helpviewer_keywords: ["-Zc:lambda compiler option (C++)", "/Zc:lambda compiler option (C++)"]
---
# `/Zc:lambda` (Enable updated lambda processor)

The **`/Zc:lambda`** compiler option enables conforming lambda grammar and processing support.

## Syntax

> **`/Zc:lambda`**[**`-`**]

## Remarks

The **`/Zc:lambda`** compiler option enables the conforming lambda processor. It parses and implements lambda code according to the C++ standard. This option is off by default, which uses the legacy lambda processor. Use this option to enable conformance-mode syntax checks of generic lambdas when you use the default [`/std:c++14`](std-specify-language-standard-version.md) or the [`/std:c++17`](std-specify-language-standard-version.md) compiler options.

**`/Zc:lambda`** is automatically enabled by the [`/std:c++20`](std-specify-language-standard-version.md), [`/std:c++latest`](std-specify-language-standard-version.md), and [`/experimental:module`](experimental-module.md) options. You can disable it explicitly by using **`/Zc:lambda-`**. The [`/permissive-`](permissive-standards-conformance.md) option doesn't enable **`/Zc:lambda`**.

The **`/Zc:lambda`** option is available starting in Visual Studio 2019 version 16.8. It's available as **`/experimental:newLambdaProcessor`** starting in Visual Studio 2019 version 16.3, but this spelling is now deprecated.

The legacy lambda processor has limitations when it parses and compiles lambdas. For example, this conforming code compiles correctly under **`/Zc:lambda`**, but reports errors under **`/Zc:lambda-`**:

```cpp
void f1()
{
constexpr auto c_value = 1;
auto func = []()
{
return c_value; // error C3493: 'c_value' cannot be implicitly captured
// because no default capture mode has been specified
};
func(); // error C2064: term does not evaluate to a function taking 0 arguments
}
```

The legacy lambda processor compiles this code without warnings, but the new lambda processor produces error C2760:

```cpp
void f2() {
auto a = [](auto arg) {
decltype(arg)::Type t; // C2760 syntax error: unexpected token 'identifier', expected ';'
};
}
```

This example shows the correct syntax, now enforced by the compiler under **`/Zc:lambda`**:

```cpp
void f3() {
auto a = [](auto arg) {
typename decltype(arg)::Type t;
};
}
```

### To set this compiler option in Visual Studio

1. Open the project's **Property Pages** dialog box. For details, see [Set C++ compiler and build properties in Visual Studio](../working-with-project-properties.md).

1. Select the **Configuration Properties** > **C/C++** > **Command Line** property page.

1. Add **`/Zc:lambda`** or **`/Zc:lambda-`** to the **Additional options:** pane.

## See also

[`/Zc` (Conformance)](zc-conformance.md)\
[`/std` (Specify language standard version)](std-specify-language-standard-version.md)
3 changes: 3 additions & 0 deletions docs/build/toc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -773,6 +773,9 @@
href: ../build/reference/zc-implicitnoexcept-implicit-exception-specifiers.md
- name: "/Zc:inline (Remove unreferenced COMDAT)"
href: ../build/reference/zc-inline-remove-unreferenced-comdat.md
- name: "/Zc:lambda (Enable updated lambda processor)"
href: ../build/reference/zc-lambda.md
- name: "/Zc:preprocessor (Enable preprocessor conformance mode)"
- name: "/Zc:noexceptTypes (C++17 noexcept rules)"
href: ../build/reference/zc-noexcepttypes.md
- name: "/Zc:preprocessor (Enable preprocessor conformance mode)"
Expand Down
28 changes: 14 additions & 14 deletions docs/cpp/program-and-linkage-cpp.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
---
description: "Learn more about: Translation units and linkage"
title: "Translation units and linkage (C++)"
ms.date: "12/11/2019"
ms.date: 08/12/2021
ms.assetid: a6493ba0-24e2-4c89-956e-9da1dea660cb
---
# Translation units and linkage

In a C++ program, a *symbol*, for example a variable or function name, can be declared any number of times within its scope, but it can only be defined once. This rule is the "One Definition Rule" (ODR). A *declaration* introduces (or re-introduces) a name into the program. A *definition* introduces a name. If the name represents a variable, a definition explicitly initializes it. A *function definition* consists of the signature plus the function body. A class definition consists of the class name followed by a block that lists all the class members. (The bodies of member functions may optionally be defined separately in another file.)
In a C++ program, a *symbol*, for example a variable or function name, can be declared any number of times within its scope. However, it can only be defined once. This rule is the "One Definition Rule" (ODR). A *declaration* introduces (or reintroduces) a name into the program, along with enough information to later associate the name with a definition. A *definition* introduces a name and provides all the information needed to create it. If the name represents a variable, a definition explicitly creates storage and initializes it. A *function definition* consists of the signature plus the function body. A class definition consists of the class name followed by a block that lists all the class members. (The bodies of member functions may optionally be defined separately in another file.)

The following example shows some declarations:

Expand All @@ -27,35 +27,35 @@ public:
};
```

A program consists of one or more *translation units*. A translation unit consists of an implementation file and all the headers that it includes directly or indirectly. Implementation files typically have a file extension of *cpp* or *cxx*. Header files typically have an extension of *h* or *hpp*. Each translation unit is compiled independently by the compiler. After the compilation is complete, the linker merges the compiled translation units into a single *program*. Violations of the ODR rule typically show up as linker errors. Linker errors occur when the same name has two different definitions in different translation units.
A program consists of one or more *translation units*. A translation unit consists of an implementation file and all the headers that it includes directly or indirectly. Implementation files typically have a file extension of *`.cpp`* or *`.cxx`*. Header files typically have an extension of *`.h`* or *`.hpp`*. Each translation unit is compiled independently by the compiler. After the compilation is complete, the linker merges the compiled translation units into a single *program*. Violations of the ODR rule typically show up as linker errors. Linker errors occur when the same name has two different definitions in different translation units.

In general, the best way to make a variable visible across multiple files is to put it in a header file. Then add an #include directive in every *cpp* file that requires the declaration. By adding *include guards* around the header contents, you ensure that the names it declares are only defined once.
In general, the best way to make a variable visible across multiple files is to put it in a header file. Then add an #include directive in every *`.cpp`* file that requires the declaration. By adding *include guards* around the header contents, you ensure that the names it declares are only defined once.

In C++20, [modules](modules-cpp.md) are introduced as an improved alternative to header files.

In some cases it may be necessary to declare a global variable or class in a *cpp* file. In those cases, you need a way to tell the compiler and linker what kind of *linkage* the name has. The type of linkage specifies whether the name of the object applies just to the one file, or to all files. The concept of linkage applies only to global names. The concept of linkage does not apply to names that are declared within a scope. A scope is specified by a set of enclosing braces such as in function or class definitions.
In some cases, it may be necessary to declare a global variable or class in a *`.cpp`* file. In those cases, you need a way to tell the compiler and linker what kind of *linkage* the name has. The type of linkage specifies whether the name of the object applies just to the one file, or to all files. The concept of linkage applies only to global names. The concept of linkage doesn't apply to names that are declared within a scope. A scope is specified by a set of enclosing braces such as in function or class definitions.

## External vs. internal linkage

A *free function* is a function that is defined at global or namespace scope. Non-const global variables and free functions by default have *external linkage*; they are visible from any translation unit in the program. Therefore, no other global object can have that name. A symbol with *internal linkage* or *no linkage* is visible only within the translation unit in which it is declared. When a name has internal linkage, the same name may exist in another translation unit. Variables declared within class definitions or function bodies have no linkage.
A *free function* is a function that is defined at global or namespace scope. Non-const global variables and free functions by default have *external linkage*; they're visible from any translation unit in the program. No other global object can have that name. A symbol with *internal linkage* or *no linkage* is visible only within the translation unit in which it's declared. When a name has internal linkage, the same name may exist in another translation unit. Variables declared within class definitions or function bodies have no linkage.

You can force a global name to have internal linkage by explicitly declaring it as **`static`**. This limits its visibility to the same translation unit in which it is declared. In this context, **`static`** means something different than when applied to local variables.
You can force a global name to have internal linkage by explicitly declaring it as **`static`**. This keyword limits its visibility to the same translation unit in which it's declared. In this context, **`static`** means something different than when applied to local variables.

The following objects have internal linkage by default:

- const objects
- constexpr objects
- typedefs
- static objects in namespace scope
- **`const`** objects
- **`constexpr`** objects
- **`typedef`** objects
- **`static`** objects in namespace scope

To give a const object external linkage, declare it as **`extern`** and assign it a value:
To give a **`const`** object external linkage, declare it as **`extern`** and assign it a value:

```cpp
extern const int value = 42;
```

See [extern](extern-cpp.md) for more information.
For more information, see [`extern`](extern-cpp.md).

## See also

[Basic Concepts](../cpp/basic-concepts-cpp.md)
[Basic concepts](../cpp/basic-concepts-cpp.md)
26 changes: 24 additions & 2 deletions docs/error-messages/compiler-errors-2/compiler-error-c2760.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
---
description: "Learn more about: Compiler Error C2760"
title: "Compiler Error C2760"
ms.date: "11/04/2016"
ms.date: 08/12/2021
f1_keywords: ["C2760"]
helpviewer_keywords: ["C2760"]
ms.assetid: 585757fd-d519-43f3-94e5-50316ac8b90b
---
# Compiler Error C2760

> syntax error : expected '*name1*' not '*name2*'
> syntax error : expected '*name1*' not '*name2*'\
> syntax error : unexpected token '*token1*', expected '*token2*'\
> syntax error: '*token1*' was unexpected here; expected '*token2*'

## Remarks

Expand All @@ -29,3 +31,23 @@ void f(B* pb) {
D* pd3 = static_cast<D*=(pb); // C2760
}
```

The new lambda processor available under [`/std:c++20`](../../build/reference/std-specify-language-standard-version.md) or later, or under [`/Zc:lambda`](../../build/reference/zc-lambda.md), enables some new conformance-mode syntactic checks in generic lambdas. The legacy lambda processor compiles this code without warnings, but the new lambda processor produces error C2760:

```cpp
void f() {
auto a = [](auto arg) {
decltype(arg)::Type t; // C2760 syntax error: unexpected token 'identifier', expected ';'
};
}
```

This example shows the correct syntax, now enforced by the compiler, which works in all **`/std`** modes:

```cpp
void f() {
auto a = [](auto arg) {
typename decltype(arg)::Type t;
};
}
```
Loading