Alc*_*ott 39 c c++ compilation
在C++中,我倾向于在某些情况下省略参数的名称.但是在C中,当我省略参数的名字时出错了.
这是代码:
void foo(int); //forward-decl, it's OK to omit the parameter's name, in both C++ and C
int main()
{
foo(0);
return 0;
}
void foo(int) //definition in C, it cannot compile with gcc
{
printf("in foo\n");
}
void foo(int) //definition in C++, it can compile with g++
{
cout << "in foo" << endl;
}
Run Code Online (Sandbox Code Playgroud)
这是为什么?我不能省略C函数定义中的参数名称吗?
adl*_*adl 34
不,在C中,您不能省略函数定义中参数的标识符.
C99标准说:
[6.9.1.5]如果声明者包含参数类型列表,则每个参数的声明应包括一个标识符,但参数列表的特殊情况除外,该参数列表由void类型的单个参数组成,在这种情况下,不应存在标识符.不得遵循声明清单.
C++ 14标准说:
[8.3.5.11] 可以选择提供标识符作为参数名称; 如果存在于函数定义中,它会命名一个参数(有时称为"形式参数").[注意:特别是,参数名称在函数定义和名称中也是可选的,用于不同声明中的参数,并且函数的定义不必相同.
Kei*_*son 16
原因在于这就是各自的语言标准所说的,但是存在差异的理由.
如果没有为参数提供名称,则该函数不能引用该参数.
在C中,如果一个函数忽略了它的一个参数,通常只需要从声明和定义中删除它,而不是在任何调用中传递它.异常可能是回调函数,其中函数集合必须是相同类型,但并非所有函数都必须使用它们的参数.但这不是一个非常常见的情况.
在C++中,如果函数是从某个父类中定义的函数派生的,则它必须与父元素具有相同的签名,即使子函数没有使用其中一个参数值.
(请注意,这与默认参数无关;如果C++中的参数具有默认值,则调用者不必显式传递它,但如果函数定义将引用它,则仍必须提供名称. )
在纯粹实用的层面上,我每天都会处理这个问题.迄今为止最好的解决方案是使用预处理器.我的通用头文件包含:
//-------------------------------------------------------------------------
// Suppress nuisance compiler warnings. Yes, each compiler can already
// do this, each differently! VC9 has its UNREFERENCED_PARAMETER(),
// which is almost the same as the SUPPRESS_UNUSED_WARNING() below.
//
// We append _UNUSED to the variable name, because the dumb gcc compiler
// doesn't bother to tell you if you erroneously _use_ something flagged
// with __attribute__((unused)). So we are forced to *mangle* the name.
//-------------------------------------------------------------------------
#if defined(__cplusplus)
#define UNUSED(x) // = nothing
#elif defined(__GNUC__)
#define UNUSED(x) x##_UNUSED __attribute__((unused))
#else
#define UNUSED(x) x##_UNUSED
#endif
Run Code Online (Sandbox Code Playgroud)
使用UNUSED的一个例子是:
void foo(int UNUSED(bar)) {}
Run Code Online (Sandbox Code Playgroud)
有时您实际需要引用参数,例如在assert()或debug语句中.你可以这样做:
#define USED_UNUSED(x) x##_UNUSED // for assert(), debug, etc
Run Code Online (Sandbox Code Playgroud)
此外,以下内容非常有用:
#define UNUSED_FUNCTION(x) inline static x##_UNUSED // "inline" for GCC warning
#define SUPPRESS_UNUSED_WARNING(x) (void)(x) // cf. MSVC UNREFERENCED_PARAMETER
Run Code Online (Sandbox Code Playgroud)
例子:
UNUSED_FUNCTION(int myFunction)(int myArg) { ...etc... }
Run Code Online (Sandbox Code Playgroud)
和:
void foo(int bar) {
#ifdef XXX
// ... (some code using bar)
#else
SUPPRESS_UNUSED_WARNING(bar);
#endif
}
Run Code Online (Sandbox Code Playgroud)