C++中的extern "C"是否适用于默认参数?

8

根据这里的信息,C语言不支持默认参数。

我在导出库中有以下方法:

extern "C" 
{
    __declspec (dllexport) uintptr_t Method(int freq, int *pRetval, bool *support2MHz);
}

如果我将最后一个参数改为可选项,代码会变成这样:
extern "C" 
{
    __declspec (dllexport) uintptr_t Method(int freq, int *pRetval, bool *support2MHz = NULL);
}

我的dll仍旧被编译。我的问题是为什么?大家都说C代码不支持默认参数。

我使用的是MS 2015的C++。


2
我认为它能够工作是因为默认参数由调用者处理。 - Tyker
4
extern "C"不意味着“这是C代码”,它只影响导出符号的形式(即“方法”)。如果将其提供给C编译器,它将抱怨extern "C"和默认参数。 - molbdnilo
2
据我所知,当您尝试使用此导出时,仍需要提供3个参数。这是C++,因此您可以在此处提供默认参数,但是当您尝试使用导出的C函数时,您需要提供所有3个参数。 - Afshin
@Afshin “使用导出的 C 函数”,您是指在 C 代码还是 C++ 代码中使用导出的函数? - John
@John 我的意思是当你想在 C 代码中使用导出的 C++ 代码时。 - Afshin
1个回答

8
正如molbdnilo在评论中指出的那样,extern "C"并不意味着“这是C代码”,而是“这是具有C链接的代码”——即该函数的名称重载将不会被执行,因此您可以使用“预期”的函数调用语法从C中调用它。 C ++编译器对函数名进行名称重载,以便支持函数重载,因为同一函数的不同重载的符号名称必须是唯一的(基本上,它们使用函数的作用域,名称和参数类型来创建唯一的符号名称)。
根据标准[dcl.fct.default]的第1和第2段:

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 ]

此外,第9段指定:

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 ]

因此,对于一个带有默认参数的函数 int foo(int x, int y = 0),编译器不会生成两个重载函数(int foo(int x, int y)int foo(int x),其中 y 固定为 0),而是将形如 foo(x) 的每个调用替换为调用 foo(x, 0)。在您具体的带有 extern "C" 的示例中,这意味着编译器仅为 Method 生成一个具有 C 链接的符号,因此不存在名称冲突。
您可以在godbolt 上的实时示例中查看各种编译器的行为。
然而,正如 Afshin 在评论中已经提到的那样,这种实现方式使得无法向其他使用您共享库的用户传播默认参数,因此,如果您想从 C 中使用它,则仍需要将所有参数传递给函数。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接