参数名称省略,C++ vs C.

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] 可以选择提供标识符作为参数名称; 如果存在于函数定义中,它会命名一个参数(有时称为"形式参数").[注意:特别是,参数名称在函数定义名称中也是可选的,用于不同声明中的参数,并且函数的定义不必相同.

  • @ Mr.TAMER:所有变量名都是标识符,但有些标识符不是变量名. (6认同)
  • @Alcott:键入名称,函数名称,宏名称,标记名称,标签名称:all都可以是标识符. (4认同)

Kei*_*son 16

原因在于这就是各自的语言标准所说的,但是存在差异的理由.

如果没有为参数提供名称,则该函数不能引用该参数.

在C中,如果一个函数忽略了它的一个参数,通常只需要从声明和定义中删除它,而不是在任何调用中传递它.异常可能是回调函数,其中函数集合必须是相同类型,但并非所有函数都必须使用它们的参数.但这不是一个非常常见的情况.

在C++中,如果函数是从某个父类中定义的函数派生的,则它必须与父元素具有相同的签名,即使子函数没有使用其中一个参数值.

(请注意,这与默认参数无关;如果C++中的参数具有默认值,则调用者不必显式传递它,但如果函数定义将引用它,则仍必须提供名称. )


Jos*_*sey 5

在纯粹实用的层面上,我每天都会处理这个问题.迄今为止最好的解决方案是使用预处理器.我的通用头文件包含:

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