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

发布于 2024-12-25 19:13:49 字数 453 浏览 4 评论 0原文

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

In C++, I tend to omit the parameter's name under some circumstances. But in C, I got an error when I omitted the parameter's name.

Here is the code:

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;
}

Why is that? Can't I omit the parameter's name in C function definition?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

缺⑴份安定 2025-01-01 19:13:49

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

C99标准说:

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

C++14 标准规定:

[8.3.5.11] 可以选择将标识符作为参数提供
姓名;如果出现在函数定义中,它会命名一个参数
(有时称为“形式论证”)。 [注:特别是参数
函数定义中的名称也是可选的,并且用于
不同声明和函数定义中的参数
不必相同。]


No, in C you cannot omit identifiers for parameters in function definitions.

The C99 standard says:

[6.9.1.5] If the declarator includes a parameter type list, the
declaration of each parameter shall include an identifier, except for
the special case of a parameter list consisting of a single parameter
of type void, in which case there shall not be an identifier. No
declaration list shall follow.

The C++14 standard says:

[8.3.5.11] An identifier can optionally be provided as a parameter
name; if present in a function definition , it names a parameter
(sometimes called “formal argument”). [Note: In particular, parameter
names are also optional in function definitions
and names used for a
parameter in different declarations and the definition of a function
need not be the same.]

桃酥萝莉 2025-01-01 19:13:49

原因是各自的语言标准都是这么说的,但差异是有原因的。

如果您不提供参数名称,则该函数无法引用该参数。

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

在 C++ 中,如果函数派生自某个父类中定义的函数,则它必须具有与父类相同的签名,即使子函数不使用参数值之一。

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

更新:C 标准的下一版本(C23、ISO/IEC 9899:2023 (E))很可能将允许省略参数名称。

The reason is that that's what the respective language standards say, but there is a rationale for the difference.

If you don't provide a name for a parameter, then the function cannot refer to that parameter.

In C, if a function ignores one of its parameters, it usually makes sense just to remove it from the declaration and the definition, and not pass it in any calls. An exception might be a callback function, where a collection of functions all have to be of the same type but not all of them necessarily use their parameters. But that's not a very common scenario.

In C++, if the function is derived from a function defined in some parent class, it has to have the same signature as the parent, even if the child function has no use for one of the parameter values.

(Note that this is not related to default parameters; if a parameter in C++ has a default value, the caller doesn't have to pass it explicitly, but the function definition still has to provide a name if it's going to refer to it.)

UPDATE: It's likely that the next edition of the C standard (C23, ISO/IEC 9899:2023 (E)) will allow parameter names to be omitted.

玩套路吗 2025-01-01 19:13:49

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

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

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

#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
}

On a purely practical level, I have deal with this daily. The best solution to date is to use the pre-processor. My common header file contains:

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

An example of the use of UNUSED is:

void foo(int UNUSED(bar)) {}

Sometimes you actually need to refer to the parameter, for example in an assert() or debug statement. You can do so via:

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

Also, the following are useful:

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

Examples:

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

and:

void foo(int bar) {
#ifdef XXX
   // ... (some code using bar)
#else
   SUPPRESS_UNUSED_WARNING(bar);
#endif
}
长途伴 2025-01-01 19:13:49

函数原型中可以省略参数名称,但必须在函数实现中声明。例如,在 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 中的函数提供所有参数,则编译器将抛出错误:函数'foo'的参数太少

You can omit the parameter name in the function prototype, but you must declare it in the function implementation. For example, this compiles and runs just fine under 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;
}

Outputs: In foo with value 10 and 15!

As to why (other than because the standards say so): C++ allows you to call a function without using all of the arguments, while C doesn't. If you don't supply all the arguments to a function in C, then the compiler will throw error: too few arguments to function 'foo'

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文