有人在演示中声称如果你添加
#define struct union
#define else
在任何有效的 C 程序开头,该程序仍然会编译。这似乎是一个大胆的主张。你有什么反例并证明那个人错了吗?
答案 0 :(得分:12)
我设法找到了一个反例(C99):
for (int i = 0; i < 5; ++i)
if (i > 2)
do_smth();
else if (i < 4)
do_smth_else();
这个不编译,因为如果#define else
变量i
超出范围。但这并不涉及#define struct union
事。还有其他想法吗?
答案 1 :(得分:7)
#define struct union
struct OBJ
{
int i1;
double d1;
};
int foo()
{
struct OBJ obj = { 1, 2.0 };
return 0;
}
C2078:初始化程序太多
答案 2 :(得分:5)
else
声明的另一个反例,我想回到K&amp; R C:
void do_something() {}
do
if (1) do_something(); else do_something();
while(0);
do
必须紧跟一个语句。 if (condition) statement; else statement;
构成一个陈述,但是消除else
将导致它成为两个陈述。
至于struct vs union,给出
typedef union {int x, y; } t;
t a[3] = {1,2,3};
我认为编译器需要将3存储到a[2].x
(也称为a[2].y
),并且无处存储任何其他初始化值。如果t
是一个结构,则3将进入a[1].x
,并且还有三个值的空间。
答案 3 :(得分:0)
如果STATIC_ASSERT()
是您最喜欢的静态断言宏,那么:
struct {int a, b, c, d;} x;
//...
STATIC_ASSERT(sizeof x == 4 * sizeof(int));
如果你有#define struct union
,将无法编译。
答案 4 :(得分:0)
#define else 42
如果在其前面添加#define else
,则无效(因此可能无法编译)。
当前定义为类似对象的宏的标识符不应重新定义 另一个#define预处理指令,除非第二个定义是一个类似对象的宏 定义和两个替换列表是相同的。
(ISO / IEC 9899:1999,§6.10.3,2)