Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

extern "C" Default argument works or not?

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.

like image 270
Erik Šťastný Avatar asked May 28 '18 12:05

Erik Šťastný


People also ask

Can we use default arguments in C?

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.

Which case default argument passing in function is not allowed?

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?

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.

What is the purpose of extern C?

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.


1 Answers

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) and point(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.

like image 76
gflegar Avatar answered Sep 29 '22 17:09

gflegar