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.
Yes. :-) But not in a way you would expect. Unfortunately, C doesn't allow you to overload methods so you'd end up with two different functions. Still, by calling f2, you'd actually be calling f1 with a default value.
Default arguments are only allowed in the parameter lists of function declarations and lambda-expressions, (since C++11) and are not allowed in the declarations of pointers to functions, references to functions, or in typedef declarations.
Which among the following is false for default arguments? Explanation: The statements given are true because that is a feature given to make the programming more flexible and have some security with accidental changes at same time. The last option is false because it is not a rule defined.
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. In a template declaration, extern specifies that the template has already been instantiated elsewhere.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With