在浏览一些大量混合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的副本,因为它特别询问了功能签名的含义,而不是更为一般的“有什么区别”。
答案 0 :(得分:8)
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
用作参数类型时,似乎void
尝试与$(function($) {
$.fn.initPlugin1 = function() {
console.log('Initialized Plugin1');
return $(this);
};
$.fn.initPlugin1.testFunction = function() {
$(this).append('Function 1.');
};
});
,中的不同类型。
答案 1 :(得分:5)
评论解释了差异。给定void
的别名:
typedef void MY_VOID;
如果您尝试使用此代替void
来表示函数不带参数:
int f(MY_VOID);
C将允许这样做,但C ++不会。
所以,如果你真的想通过编写(a)在两种语言中都有效的代码和(b)使用void
的这种特殊用法的别名来让自己变得困难,那么别名将不得不是一个宏观。
答案 2 :(得分:3)
评论指的是这样的代码:
typedef void my_void_t;
my_void_t foo(my_void_t); // Illegal.
使用#define
是合法的。
答案 3 :(得分:1)
语言标准的摘录可以使一切变得更好!
C99,6.7.5.3/10:
void类型的未命名参数的特殊情况,作为列表中唯一的项目,指定该函数没有参数。
C ++,8.3.5 / 2:
如果parameter-declaration-clause为空,则该函数不带参数。参数列表(void)等同于空参数列表。
区别很明显。 C将void
作为void
类型的未命名参数,并且C ++具有标识符void
。前者可以是typedef
- ed,后者可以是<。
考虑其原因可能会很有趣。实际上,以下内容在C ++中是合法的,但在C:中是非法的
void fn(int){
}
由于C ++在函数定义中具有未命名(匿名)参数的概念,而C几乎没有......几乎。
实际上,一个未命名的参数可以出现在C函数定义中:类型void
之一。
这绝对没什么意义,因为这种类型的名称参数没有。
除了没有意义之外,参数列表中void
的这个定义可能会搞砸C ++的未命名参数,因为它们与它们没有什么不同。该定义可以修改为使其成为非常非常特殊情况的未命名参数,该参数没有相应的命名参数,不能与其他命名或未命名参数一起使用,实际上不是参数和...
但我想这不是试图说出像那样疯狂的东西,而是C ++委员会决定放弃&#34; unnamed-void-type-parameter&#34;完全填充并使用&#34;特殊参数列表&#34;。我说好了解。
和C标准?出于向后兼容的原因,它可能会保留其奇怪的6.7.5.3/10 ......
答案 4 :(得分:-1)
你可以同时使用它们,它们正在做同样的事情,所以使用#define的唯一区别就是你将新类型声明为宏。