Skip to content

Commit ca57cec

Browse files
authored
Merge pull request #3956 from corob-msft/docs/corob/zc-externc-1594
Add `/Zc:externC` compiler option doc, fix 1594
2 parents 445d457 + 4d28898 commit ca57cec

File tree

6 files changed

+80
-17
lines changed

6 files changed

+80
-17
lines changed

docs/build/reference/zc-conformance.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
title: "/Zc (Conformance)"
33
description: "The /Zc conformance compiler options enable or disable support for conforming or backward-compatible behavior."
4-
ms.date: 08/12/2021
4+
ms.date: 12/02/2021
55
helpviewer_keywords: ["/Zc compiler options [C++]", "-Zc compiler options [C++]", "Conformance compiler options", "Zc compiler options [C++]"]
66
---
77
# `/Zc` (Conformance)
@@ -26,6 +26,7 @@ Here are the **`/Zc`** compiler options:
2626
| [`/Zc:auto`](zc-auto-deduce-variable-type.md) | Enforce the new Standard C++ meaning for **`auto`** (on by default). |
2727
| [`/Zc:char8_t`](zc-char8-t.md) | Enable or disable C++20 native `u8` literal support as `const char8_t` (off by default, except under **`/std:c++20`**). |
2828
| [`/Zc:__cplusplus`](zc-cplusplus.md) | Enable the `__cplusplus` macro to report the supported standard (off by default). |
29+
| [`/Zc:externC`](zc-externc.md) | Enforce Standard C++ rules for `extern "C"` functions (implied by **`/permissive-`**). |
2930
| [`/Zc:externConstexpr`](zc-externconstexpr.md) | Enable external linkage for **`constexpr`** variables (off by default). |
3031
| [`/Zc:forScope`](zc-forscope-force-conformance-in-for-loop-scope.md) | Enforce Standard C++ **`for`** scoping rules (on by default). |
3132
| [`/Zc:hiddenFriend`](zc-hiddenfriend.md) | Enforce Standard C++ hidden friend rules (implied by **`/permissive-`**) |

docs/build/reference/zc-externc.md

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
---
2+
description: 'Learn more about: /Zc:externC (Use Standard C++ extern "C" rules)'
3+
title: '/Zc:externC (Use Standard C++ extern "C" rules)'
4+
ms.date: 12/02/2021
5+
f1_keywords: ["/Zc:externC"]
6+
helpviewer_keywords: ["-Zc:externConstexpr compiler option (C++)", "extern constexpr variables (C++)"]
7+
ms.assetid: 4da5e33a-2e4d-4ed2-8616-bd8f43265c27
8+
---
9+
# `/Zc:externC` (Use Standard C++ `extern "C"` rules)
10+
11+
The **`/Zc:externC`** compiler option tells the compiler to conform to the C++ standard and enforce consistent parameter declarations for functions declared as `extern "C"`.
12+
13+
## Syntax
14+
15+
> **`/Zc:externC`**\
16+
> **`/Zc:externC-`**
17+
18+
## Remarks
19+
20+
The **`/Zc:externC`** compiler option checks the definitions of functions declared by using `extern "C"`.
21+
22+
The **`/Zc:externC`** option is available starting in Visual Studio 2019 version 16.3. It's off when the [`/permissive-`](permissive-standards-conformance.md) option isn't set. In earlier versions of Visual Studio, and by default or if **`/Zc:externC-`** is specified, Visual Studio is permissive about matching declarations of `extern "C"` functions. The **`/permissive-`** option enables **`/Zc:externC`**, so it's on by default in projects that use **`/std:c++20`** or **`/std:c++latest`**. The **`/Zc:externC`** option must come after a **`/permissive-`** option on the command line.
23+
24+
Mismatched `extern "C"` declarations can cause compiler errors [C2116](../../error-messages/compiler-errors-1/compiler-error-c2116.md) and [C2733](../../error-messages/compiler-errors-2/compiler-error-c2733.md). In C++ code, an error can occur if you declare an `extern "C"` function more than once and use different parameter types, even if the types have the same definitions. The **`/Zc:externC-`** option relaxes this check, and doesn't produce these errors.
25+
26+
### To set this compiler option in Visual Studio
27+
28+
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).
29+
30+
1. Select the **Configuration Properties** > **C/C++** > **Command Line** property page.
31+
32+
1. Add **`/Zc:externC`** or **`/Zc:externC-`** to the **Additional options:** pane.
33+
34+
## See also
35+
36+
[`/Zc` (Conformance)](zc-conformance.md)

docs/build/toc.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -772,6 +772,8 @@ items:
772772
href: ../build/reference/zc-char8-t.md
773773
- name: "/Zc:__cplusplus (Enable updated __cplusplus macro)"
774774
href: ../build/reference/zc-cplusplus.md
775+
- name: '/Zc:externC (Use Standard C++ extern "C" rules)'
776+
href: ../build/reference/zc-externc.md
775777
- name: "/Zc:externConstexpr (Enable extern constexpr variables)"
776778
href: ../build/reference/zc-externconstexpr.md
777779
- name: "/Zc:forScope (Force conformance in for loop scope)"

docs/cpp/extern-cpp.md

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
---
22
title: "extern (C++)"
33
description: "Guide to the C++ language extern keyword."
4-
ms.date: "01/28/2020"
4+
ms.date: 12/02/2021
55
f1_keywords: ["extern", "extern_CPP"]
66
helpviewer_keywords: ["extern keyword [C++], linkage to non-C++ functions", "declarations, external", "external linkage, extern modifier"]
77
ms.assetid: 1e2f0ae3-ae98-4410-85b5-222d6abc865a
88
no-loc: [extern, const, constexpr, permissive]
99
---
10-
# extern (C++)
10+
# `extern` (C++)
1111

1212
The **`extern`** keyword may be applied to a global variable, function, or template declaration. It specifies that the symbol has *external linkage*. For background information on linkage and why the use of global variables is discouraged, see [Translation units and linkage](program-and-linkage-cpp.md).
1313

@@ -17,11 +17,11 @@ The **`extern`** keyword has four meanings depending on the context:
1717

1818
- In a **`const`** variable declaration, it specifies that the variable has external linkage. The **`extern`** must be applied to all declarations in all files. (Global **`const`** variables have internal linkage by default.)
1919

20-
- **extern "C"** specifies that the function is defined elsewhere and uses the C-language calling convention. The extern "C" modifier may also be applied to multiple function declarations in a block.
20+
- **`extern "C"`** specifies that the function is defined elsewhere and uses the C-language calling convention. The `extern "C"` modifier may also be applied to multiple function declarations in a block.
2121

2222
- In a template declaration, **`extern`** specifies that the template has already been instantiated elsewhere. **`extern`** tells the compiler it can reuse the other instantiation, rather than create a new one at the current location. For more information about this use of **`extern`**, see [Explicit instantiation](explicit-instantiation.md).
2323

24-
## extern linkage for non-const globals
24+
## `extern` linkage for non-`const` globals
2525

2626
When the linker sees **`extern`** before a global variable declaration, it looks for the definition in another translation unit. Declarations of non-**`const`** variables at global scope are external by default. Only apply **`extern`** to the declarations that don't provide the definition.
2727

@@ -40,7 +40,7 @@ int i = 43; // LNK2005! 'i' already has a definition.
4040
extern int i = 43; // same error (extern is ignored on definitions)
4141
```
4242

43-
## extern linkage for const globals
43+
## `extern` linkage for `const` globals
4444

4545
A **`const`** global variable has internal linkage by default. If you want the variable to have external linkage, apply the **`extern`** keyword to the definition, and to all other declarations in other files:
4646

@@ -52,9 +52,9 @@ extern const int i = 42; // extern const definition
5252
extern const int i; // declaration only. same as i in FileA
5353
```
5454

55-
## extern constexpr linkage
55+
## `extern constexpr` linkage
5656

57-
In Visual Studio 2017 version 15.3 and earlier, the compiler always gave a **`constexpr`** variable internal linkage, even when the variable was marked **`extern`**. In Visual Studio 2017 version 15.5 and later, the [/Zc:externConstexpr](../build/reference/zc-externconstexpr.md) compiler switch enables correct standards-conforming behavior. Eventually the option will become the default. The [/permissive-](../build/reference/permissive-standards-conformance.md) option doesn't enable **/Zc:externConstexpr**.
57+
In Visual Studio 2017 version 15.3 and earlier, the compiler always gave a **`constexpr`** variable internal linkage, even when the variable was marked **`extern`**. In Visual Studio 2017 version 15.5 and later, the [`/Zc:externConstexpr`](../build/reference/zc-externconstexpr.md) compiler switch enables correct standards-conforming behavior. Eventually the option will become the default. The [`/permissive-`](../build/reference/permissive-standards-conformance.md) option doesn't enable **`/Zc:externConstexpr`**.
5858

5959
```cpp
6060
extern constexpr int x = 10; //error LNK2005: "int const x" already defined
@@ -66,11 +66,11 @@ If a header file contains a variable declared **`extern`** **`constexpr`**, it m
6666
extern constexpr __declspec(selectany) int x = 10;
6767
```
6868
69-
## extern "C" and extern "C++" function declarations
69+
## `extern "C"` and `extern "C++"` function declarations
7070
7171
In C++, when used with a string, **`extern`** specifies that the linkage conventions of another language are being used for the declarator(s). C functions and data can be accessed only if they're previously declared as having C linkage. However, they must be defined in a separately compiled translation unit.
7272
73-
Microsoft C++ supports the strings **"C"** and **"C++"** in the *string-literal* field. All of the standard include files use the **extern "C"** syntax to allow the run-time library functions to be used in C++ programs.
73+
Microsoft C++ supports the strings **`"C"`** and **`"C++"`** in the *string-literal* field. All of the standard include files use the **`extern "C"`** syntax to allow the run-time library functions to be used in C++ programs.
7474
7575
## Example
7676
@@ -111,7 +111,7 @@ extern "C" char GetChar(void) {
111111
extern "C" int errno;
112112
```
113113

114-
If a function has more than one linkage specification, they must agree. It's an error to declare functions as having both C and C++ linkage. Furthermore, if two declarations for a function occur in a programone with a linkage specification and one without the declaration with the linkage specification must be first. Any redundant declarations of functions that already have linkage specification are given the linkage specified in the first declaration. For example:
114+
If a function has more than one linkage specification, they must agree. It's an error to declare functions as having both C and C++ linkage. Furthermore, if two declarations for a function occur in a program, one with a linkage specification and one without, the declaration with the linkage specification must be first. Any redundant declarations of functions that already have linkage specification are given the linkage specified in the first declaration. For example:
115115

116116
```cpp
117117
extern "C" int CFunc1();
@@ -126,6 +126,8 @@ extern "C" int CFunc2(); // Error: not the first declaration of
126126
// specifier.
127127
```
128128
129+
Starting in Visual Studio 2019, when **`/permissive-`** is specified, the compiler checks that the declarations of `extern "C"` function parameters also match. You can't overload a function declared as `extern "C"`. Starting in Visual Studio 2019 version 16.3, you can override this check by using the [`/Zc:externC-`](../build/reference/zc-externc.md) compiler option after the **`/permissive-`** option.
130+
129131
## See also
130132
131133
[Keywords](../cpp/keywords-cpp.md)\
Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,25 @@
11
---
22
description: "Learn more about: Compiler Error C2116"
33
title: "Compiler Error C2116"
4-
ms.date: "11/04/2016"
4+
ms.date: 12/02/2021
55
f1_keywords: ["C2116"]
66
helpviewer_keywords: ["C2116"]
77
ms.assetid: 0089a23f-e6bd-4956-9b58-3bcca09ab5ad
88
---
99
# Compiler Error C2116
1010

11-
function parameter lists differed
11+
> function parameter lists do not match between declarations
1212
13-
The parameters in the default parameter list do not match the formal parameter list.
13+
The parameter list of a redeclared function doesn't match the parameter list used in an earlier declaration.
14+
15+
## Remarks
16+
17+
This error can occur if you use different types for the parameters when you redeclare an `extern "C"` function.
18+
19+
This error may occur after an upgrade because of conformance changes in Visual Studio 2019. Starting in Visual Studio 2019 version 16.3, the [`/Zc:externC-`](../../build/reference/zc-externc.md) compiler option relaxes this check. The option must come after any [`/permissive-`](../../build/reference/permissive-standards-conformance.md) option on the command line.
20+
21+
## See also
22+
23+
[Compiler Error C2733](../compiler-errors-2/compiler-error-c2733.md)\
24+
[`extern` (C++)](../../cpp/extern-cpp.md)\
25+
[`/Zc:externC` (Use Standard C++ `extern "C"` rules)](../../build/reference/zc-externc.md)

docs/error-messages/compiler-errors-2/compiler-error-c2733.md

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,20 @@
11
---
22
description: "Learn more about: Compiler Error C2733"
33
title: "Compiler Error C2733"
4-
ms.date: "11/04/2016"
4+
ms.date: 12/02/2021
55
f1_keywords: ["C2733"]
66
helpviewer_keywords: ["C2733"]
77
ms.assetid: 67f83561-c633-407c-a2ee-f9fd16e165bf
88
---
99
# Compiler Error C2733
1010

11-
second C linkage of overloaded function 'function' not allowed
11+
> you cannot overload a function with 'C' linkage
1212
13-
More than one overloaded function is declared with C linkage. When using C linkage, only one form of a specified function can be external. Since overloaded functions have the same undecorated name, they cannot be used with C programs.
13+
More than one overloaded function is declared with `extern "C"` linkage. When using `"C"` linkage, only one form of a specified function can be external. Since overloaded functions have the same undecorated name, they can't be used with C programs.
14+
15+
This error may occur after an upgrade because of conformance changes in Visual Studio 2019. Starting in Visual Studio 2019 version 16.3, the [`/Zc:externC-`](../../build/reference/zc-externc.md) compiler option relaxes this check. The option must come after any [`/permissive-`](../../build/reference/permissive-standards-conformance.md) option on the command line.
16+
17+
## Example
1418

1519
The following sample generates C2733:
1620

@@ -26,3 +30,9 @@ extern "C" {
2630
// void F2();
2731
}
2832
```
33+
34+
## See also
35+
36+
[Compiler Error C2116](../compiler-errors-1/compiler-error-c2116.md)\
37+
[`extern` (C++)](../../cpp/extern-cpp.md)\
38+
[`/Zc:externC` (Use Standard C++ `extern "C"` rules)](../../build/reference/zc-externc.md)

0 commit comments

Comments
 (0)