我想编译一个时间错误检查,如下所述。但是我无法在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 : ')'
任何人都可以让我知道我做错了吗?
答案 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_NULL
和0
会触发编译错误。
如果宏参数为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
表达式中定义类型,并且您的编译器选择了一种不那么清晰的方式来告诉您。