通过宏检查错误

时间:2012-12-30 02:52:19

标签: c++ c macros compiler-errors

我想编译一个时间错误检查,如下所述。但是我无法在main()内找到如何使用它?

#define BUILD_BUG_ON_ZERO(e) (sizeof(struct { int:-!!(e); }))
#define BUILD_BUG_ON_NULL(e) ((void *)sizeof(struct { int:-!!(e); }))
int main(){
BUILD_BUG_ON_NULL(12);
}

以下是提到的错误

1--error C2332: 'struct' : missing tag name
2--error C2143: syntax error : missing ')' before '{'
3--error C2027: use of undefined type 'main::<unnamed-tag>'
4--error C2143: syntax error : missing ';' before '{'
5--error C2059: syntax error : ')'

任何人都可以让我知道我做错了吗?

3 个答案:

答案 0 :(得分:4)

编辑:这个问题最初标记为C ++,但现在只是C。

我不会追问这个问题的进一步根本变化。

C ++标记问题的原始答案:


此源代码:

#define BUILD_BUG_ON_ZERO(e) (sizeof(struct { int:-!!(e); }))
#define BUILD_BUG_ON_NULL(e) ((void *)sizeof(struct { int:-!!(e); }))
int main(){
BUILD_BUG_ON_NULL(0);
}

使用g ++ 4.7.1编译,生成

foo.cpp: In function 'int main()':
foo.cpp:4:1: error: types may not be defined in 'sizeof' expressions
foo.cpp:4:21: warning: statement has no effect [-Wunused-value]

直接说错了。

因此,使用不同的编译器进行编译是个好主意。


可能你正在寻找编译时断言

使用C ++ 11,您可以使用static_assert,例如通过诸如

之类的宏
#define STATIC_ASSERT( e ) static_assert( e, #e )

在C ++ 03中,您可以将其实现为有效/无效typedef,因为typedef可以在同一个翻译单元中重复,并且可以在类定义中使用:

#define STATIC_ASSERT( e ) typedef char staticAssert_shouldBeTrue[e? 1 : -1]

一个问题是g ++有/有编译器错误,其中重复的typedef并不总是被接受,因此需要为每个错误生成一个本地唯一的名称,例如:使用__LINE__

但是你可以随时使用Boost库中的定义,因为Boost支持大多数现存的编译器,每个编译器都有必要的特殊外壳。

答案 1 :(得分:3)

首先,如果参数不同于 BUILD_BUG_ON_ZERO,则BUILD_BUG_ON_NULL0会触发编译错误。

如果宏参数为0,则它们不会触发任何编译错误,但会为0产生BUILD_BUG_ON_ZERO,为(void *) 0产生BUILD_BUG_ON_NULL

这些宏来自Linux内核,它是用C语言编写的,它们只适用于C程序。

在C ++中,这些宏正在工作。原因是在C ++中,您无法在sizeof表达式中声明结构。

你在问题​​中没有提到你是用C语言还是用C ++编译你的程序,但我强烈怀疑你是用C ++编译的。所以不要在C ++中使用这些宏。

答案 2 :(得分:1)

使用gcc -std=c99 -pedantic-errors进行编译,我得到了

screwed.c: In function ‘main’:
screwed.c:5:1: error: negative width in bit-field ‘<anonymous>’
screwed.c:5:1: error: struct has no named members [-pedantic]

并且这些是编译在编译为C时应该给出的错误。位字段的宽度必须是非负的(如果它有名称则为正),并且struct必须具有至少一个命名成员(如果最后一个是灵活的数组成员,则为两个)。允许使用没有标记的struct

您要么将代码编译为C,要么编译器不符合。

编译为C ++时,附加错误

error: types may not be defined in ‘sizeof’ expressions
生成

(但关于没有命名成员的struct的那个消失了。)

在C ++中,您可能无法在sizeof表达式中定义类型,并且您的编译器选择了一种不那么清晰的方式来告诉您。