5

我想编译如下所述的时间错误检查。但我不知道如何在里面使用它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 : ')'

谁能让我知道我做错了什么?

4

3 回答 3

5

编辑:这个问题最初被标记为 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:在函数'int main()'中:
foo.cpp:4:1:错误:类型可能未在“sizeof”表达式中定义
foo.cpp:4:21:警告:语句无效 [-Wunused-value]

这直接说明出了什么问题。

所以用不同的编译器编译是个好主意。


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

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

#define STATIC_ASSERT( e ) static_assert( e, #e )

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

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

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

但是你总是可以只使用 Boost 库中的定义,因为 Boost 支持大多数现存的编译器,每个编译器都根据需要进行特殊处理。

于 2012-12-30T03:11:48.710 回答
5

首先是宏BUILD_BUG_ON_ZEROBUILD_BUG_ON_NULL如果它们的参数不同于 0.

如果宏参数是0,它们不会触发任何编译错误,但会产生一个0forBUILD_BUG_ON_ZERO和一个(void *) 0forBUILD_BUG_ON_NULL

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

在 C++ 中,这些宏不起作用。原因是在 C++ 中,您不能在sizeof表达式中声明结构。

如果您是用 C 或 C++ 编译程序,您没有在问题中提及,但我强烈怀疑您是用 C++ 编译它。所以不要在 C++ 中使用这些宏。

于 2012-12-30T03:39:59.017 回答
2

编译gcc -std=c99 -pedantic-errors,我得到

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

这些是当代码编译为 C 时编译应该给出的错误。位域的宽度必须是非负数(如果它有名称,则为正数),并且 astruct必须至少有一个命名成员(两个,如果最后一个是灵活的数组成员)。struct允许不带标签的 s。

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

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

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

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

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

于 2012-12-30T03:15:19.563 回答