函数签名中 typedef void FOO 与 #define FOO void 的含义
Implications of typedef void FOO vs. #define FOO void in function signatures
在浏览一些大量混合使用 C 和 C++ 的源代码时,我遇到了以下内容(为了保护公司的工作而稍作修改,含义保持不变):
/*
* Typedefs of void are synonymous with the void keyword in C,
* but not in C++. In order to support the use of MY_VOID
* in place of the void keyword to specify that a function takes no
* arguments, it must be a macro rather than a typedef.
*/
#define MY_VOID void
在此特定上下文中,typedef void MY_VOID
和 #define MY_VOID void
有什么区别?
我认为这不是 this question 的重复,因为它专门询问了关于函数签名的含义,而不是更笼统的 "what's the difference"。
您可以同时使用两者,它们做同样的事情,所以唯一的区别在于使用#define 会将您的新类型声明为宏。
评论引用了这样的代码:
typedef void my_void_t;
my_void_t foo(my_void_t); // Illegal.
使用 #define
是合法的。
一个简单的 C++ 测试程序演示了不同之处:
typedef void VOID;
void f(VOID) {}
int main()
{
f();
}
编译时(作为 C++),it gives these error:
prog.cpp:5:8: error: '<anonymous>' has incomplete type
void f(VOID) {}
^
prog.cpp:5:12: error: invalid use of 'VOID {aka void}'
void f(VOID) {}
^
prog.cpp: In function 'int main()':
prog.cpp:9:7: error: too few arguments to function 'void f(<type error>)'
f();
^
prog.cpp:5:6: note: declared here
void f(VOID) {}
^
这解释了注释在您的代码中的含义。特别是,当 typedef VOID
用作参数类型 [=23] 时,它似乎试图成为与 void
、 不同的类型 =].
评论解释了差异。给定 void
的别名:
typedef void MY_VOID;
如果您尝试使用它而不是 void
来指示函数不带参数:
int f(MY_VOID);
C 允许这样做,但 C++ 不允许。
因此,如果您真的想通过编写 (a) 在两种语言中均有效且 (b) 针对 void
的特定用途使用别名的代码来让自己的生活变得困难,那么该别名将必须是宏。
语言标准的摘录可以使一切变得更好!
C99, 6.7.5.3/10:
The special case of an unnamed parameter of type void as the only item in the list specifies that the function has no parameters.
C++,8.3.5/2:
If the parameter-declaration-clause is empty, the function takes no arguments. The parameter list (void) is equivalent to the empty parameter list.
区别很明显。 C 将所讨论的 void
作为类型 void
的未命名参数,而 C++ 具有标识符 void
。前者可以typedef
-ed,后者不能。
仔细想想这其中的原因可能会很有趣。实际上,下面的语句在C++中是合法的,但在C中是非法的:
void fn(int){
}
因为C++在函数定义中有unnamed(匿名)参数的概念,而C没有...差不多。
实际上,一个未命名的参数可以出现在 C 函数定义中:void
.
类型之一
这绝对没有意义,因为这种类型没有 named 参数。
除了意义不大之外,参数列表中 void
的这种定义可能会搞砸 C++ 的未命名参数,因为它与它们没有什么不同。该定义本可以修改为 非常非常非常 未命名参数的特例,它没有相应的命名参数,不能与其他命名或未命名参数一起使用,并且不是实际上是一个参数和...
但我猜想 C++ 委员会并没有试图说出如此疯狂的话,而是简单地决定完全放弃 "unnamed-void-type-parameter" 的东西并使用 "special parameter list"。我说好吧。
C 标准呢?出于向后兼容的原因,它可能保留了奇怪的 6.7.5.3/10...
在浏览一些大量混合使用 C 和 C++ 的源代码时,我遇到了以下内容(为了保护公司的工作而稍作修改,含义保持不变):
/*
* Typedefs of void are synonymous with the void keyword in C,
* but not in C++. In order to support the use of MY_VOID
* in place of the void keyword to specify that a function takes no
* arguments, it must be a macro rather than a typedef.
*/
#define MY_VOID void
在此特定上下文中,typedef void MY_VOID
和 #define MY_VOID void
有什么区别?
我认为这不是 this question 的重复,因为它专门询问了关于函数签名的含义,而不是更笼统的 "what's the difference"。
您可以同时使用两者,它们做同样的事情,所以唯一的区别在于使用#define 会将您的新类型声明为宏。
评论引用了这样的代码:
typedef void my_void_t;
my_void_t foo(my_void_t); // Illegal.
使用 #define
是合法的。
一个简单的 C++ 测试程序演示了不同之处:
typedef void VOID;
void f(VOID) {}
int main()
{
f();
}
编译时(作为 C++),it gives these error:
prog.cpp:5:8: error: '<anonymous>' has incomplete type
void f(VOID) {}
^
prog.cpp:5:12: error: invalid use of 'VOID {aka void}'
void f(VOID) {}
^
prog.cpp: In function 'int main()':
prog.cpp:9:7: error: too few arguments to function 'void f(<type error>)'
f();
^
prog.cpp:5:6: note: declared here
void f(VOID) {}
^
这解释了注释在您的代码中的含义。特别是,当 typedef VOID
用作参数类型 [=23] 时,它似乎试图成为与 void
、 不同的类型 =].
评论解释了差异。给定 void
的别名:
typedef void MY_VOID;
如果您尝试使用它而不是 void
来指示函数不带参数:
int f(MY_VOID);
C 允许这样做,但 C++ 不允许。
因此,如果您真的想通过编写 (a) 在两种语言中均有效且 (b) 针对 void
的特定用途使用别名的代码来让自己的生活变得困难,那么该别名将必须是宏。
语言标准的摘录可以使一切变得更好!
C99, 6.7.5.3/10:
The special case of an unnamed parameter of type void as the only item in the list specifies that the function has no parameters.
C++,8.3.5/2:
If the parameter-declaration-clause is empty, the function takes no arguments. The parameter list (void) is equivalent to the empty parameter list.
区别很明显。 C 将所讨论的 void
作为类型 void
的未命名参数,而 C++ 具有标识符 void
。前者可以typedef
-ed,后者不能。
仔细想想这其中的原因可能会很有趣。实际上,下面的语句在C++中是合法的,但在C中是非法的:
void fn(int){
}
因为C++在函数定义中有unnamed(匿名)参数的概念,而C没有...差不多。
实际上,一个未命名的参数可以出现在 C 函数定义中:void
.
这绝对没有意义,因为这种类型没有 named 参数。
除了意义不大之外,参数列表中 void
的这种定义可能会搞砸 C++ 的未命名参数,因为它与它们没有什么不同。该定义本可以修改为 非常非常非常 未命名参数的特例,它没有相应的命名参数,不能与其他命名或未命名参数一起使用,并且不是实际上是一个参数和...
但我猜想 C++ 委员会并没有试图说出如此疯狂的话,而是简单地决定完全放弃 "unnamed-void-type-parameter" 的东西并使用 "special parameter list"。我说好吧。
C 标准呢?出于向后兼容的原因,它可能保留了奇怪的 6.7.5.3/10...