extern “C” Default argument works or not?

徘徊边缘 提交于 2021-01-27 03:53:25

问题


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) 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.



来源:https://stackoverflow.com/questions/50566076/extern-c-default-argument-works-or-not

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!