省略参数名称,C++与C

qyyhg6bp  于 2022-11-19  发布在  其他
关注(0)|答案(4)|浏览(206)

在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函数定义中不能省略参数的名字吗?

hiz5n14c

hiz5n14c1#

不可以,在C语言中,不能省略函数定义中参数的标识符。
C99标准规定:
[6.9.1.5]如果声明符包含参数类型列表,则每个参数的声明都应包含标识符,但由void类型的单个参数组成的参数列表的特殊情况除外,在这种情况下,不应有标识符。后面不应有声明列表。
C++14标准规定:
[8.3.5.11]标识符可以可选地作为参数名称提供;如果出现在函数定义中,它将命名一个参数(有时称为“形式参数”)。[注意:特别是,参数名称在函数定义中也是可选的,不同声明中的参数名称和函数定义不需要相同。]

bz4sfanl

bz4sfanl2#

原因是,这是各自的语言标准所说的,但有一个理由的差异。
如果不提供参数的名称,则函数无法引用该参数。
在C语言中,如果一个函数忽略了它的一个参数,通常只需要将它从声明和定义中删除,并且不通过任何调用传递它。一个例外可能是回调函数,其中一组函数必须是相同类型的,但不是所有的函数都必须使用它们的参数。但这种情况并不常见。
在C中,如果函数是从某个父类中定义的函数派生的,则它必须具有与父类相同的签名,即使子函数不使用其中一个参数值。
(Note这与默认参数无关;如果C
中的参数有默认值,调用方不必显式传递它,但函数定义在引用它时仍必须提供名称。)
更新:C标准的下一个版本(C23,ISO/IEC 9899:2023(E))可能会允许省略参数名称。

whlutmcx

whlutmcx3#

在纯粹的实践层面上,我每天都要处理这个问题。到目前为止,最好的解决方案是使用预处理器。我的公共头文件包含:

//-------------------------------------------------------------------------
//  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
}
wlzqhblo

wlzqhblo4#

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

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'

相关问题