问题
From Here it seems that default argument are not supported by C.
I have the following method in exported library:
extern "C"
{
__declspec (dllexport) uintptr_t Method(int freq, int *pRetval, bool *support2MHz);
}
If i made last argument optional like this:
extern "C"
{
__declspec (dllexport) uintptr_t Method(int freq, int *pRetval, bool *support2MHz = NULL);
}
My dll is still compiled. My question is why? Everyone says the default arguments are not supported in C code.
I use C++ for MS 2015.
回答1:
As molbdnilo already noted in the comments, extern "C"
does not mean "this is C code", but "this is code with C linkage" - i.e. name mangling for this function will not be performed, so you will be able to call it from C with the "expected" function call syntax. C++ compilers mangle the names of functions so they can support function overloading, since symbol names of different overloads of the same function have to be unique (basically, they use function's scope, name and argument types to create a unique symbol name).
According to [dcl.fct.default], paragraphs 1 and 2 of the standard:
If an initializer-clause is specified in a parameter-declaration this initializer-clause is used as a default argument. Default arguments will be used in calls where trailing arguments are missing.
[Example: The declaration
void point(int = 3, int = 4);
declares a function that can be called with zero, one, or two arguments of type
int
. It can be called in any of these ways:point(1,2); point(1); point();
The last two calls are equivalent to
point(1,4)
andpoint(3,4)
, respectively. — end example ]
In addition, paragraph 9 specifies:
A default argument is not part of the type of a function. [ Example:
int f(int = 0); void h() { int j = f(1); int k = f(); // OK, means f(0) } int (*p1)(int) = &f; int (*p2)() = &f; // error: type mismatch
— end example ]
Thus, for a function with a default argument int foo(int x, int y = 0)
, the compiler will not generate two overloads (int foo(int x, int y)
and int foo(int x)
, with y
fixed to 0
), but instead replace every call of the form foo(x)
with a call to foo(x, 0)
. In your concrete example with extern "C"
this means that the compiler generates only one symbol with C linkage for Method
so there is no name clash.
You can see this behavior for various compilers in a live example on godbolt.
However, as Afshin already mentioned in the comments, the way this is implemented makes it impossible to "propagate" default arguments to other users of your shared library, so if you want to use this from C, you'll still need to pass all arguments to the function.
来源:https://stackoverflow.com/questions/50566076/extern-c-default-argument-works-or-not