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

时间:2012-01-08 10:33:31

标签: 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;
}

为什么?我不能在C函数定义中省略参数的名称吗?

4 个答案:

答案 0 :(得分:33)

不,在C中,您不能省略函数定义中参数的标识符。

C99标准说:

  

[6.9.1.5]如果声明者包含参数类型列表,则   每个参数的声明应包括一个标识符,除了   参数列表的特例由单个参数组成   类型为void,在这种情况下不应有标识符。没有   声明清单应遵循。

C ++ 14标准说:

  

[8.3.5.11] 可以选择提供标识符作为参数   名称;如果存在于函数定义中,则为参数命名   (有时称为“正式论证”)。 [注意:特别是参数   名称在函数定义中也是可选的和用于a的名称   不同声明中的参数和函数的定义   不必相同。]

答案 1 :(得分:16)

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

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

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

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

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

答案 2 :(得分: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

使用UNUSED的一个例子是:

void foo(int UNUSED(bar)) {}

有时您实际需要引用参数,例如在assert()或debug语句中。您可以通过以下方式执行此操作:

#define USED_UNUSED(x)  x##_UNUSED // for assert(), debug, etc

此外,以下内容非常有用:

#define UNUSED_FUNCTION(x) inline static x##_UNUSED // "inline" for GCC warning
#define SUPPRESS_UNUSED_WARNING(x) (void)(x) // cf. MSVC UNREFERENCED_PARAMETER

示例:

UNUSED_FUNCTION(int myFunction)(int myArg) { ...etc... }

void foo(int bar) {
#ifdef XXX
   // ... (some code using bar)
#else
   SUPPRESS_UNUSED_WARNING(bar);
#endif
}

答案 3 :(得分:4)

您可以省略函数原型中的参数名称,但必须在函数实现中声明它。例如,这在GCC 4.6.1

下编译并运行正常
void foo(int, int);

void foo(int value, int secondValue)
{
    printf("In foo with value %d and %d!\n", value, secondValue);
}

int main(int argc, char **argv)
{
    foo(10, 15);
    return 0;
}

输出:In foo with value 10 and 15!

至于为什么(除了因为标准这样说):C ++允许你在不使用所有参数的情况下调用函数,而C则不然。如果没有为C中的函数提供所有参数,则编译器将抛出error: too few arguments to function 'foo'