我想对C / C ++项目中的数据类型大小执行编译时检查,并在意外不匹配时执行错误。简单
#if sizeof foo_t != sizeof bar_t
不编译 - 声称sizeof不是正确的编译时常量。
所需的平台范围 - 至少使用Win32 / 64的Visual C ++和x86 / amd64上的GCC。
编辑:编译时,不一定是预处理器。只是不是运行时错误。
EDIT2 :代码假定wchar_t
为2个字节。如果用4字节的wchar意外编译,我想要编译错误。
答案 0 :(得分:10)
在C ++ 11中,您可以使用静态断言
static_assert(sizeof(foo_t) == sizeof(bar_t), "sizes do not match");
如果它是C ++之前的11,那么你可以使用boost static assert macro
http://www.boost.org/doc/libs/1_48_0/doc/html/boost_staticassert.html
BOOST_STATIC_ASSERT(sizeof(int)==sizeof(unsigned));
BOOST_STATIC_ASSERT_MSG(sizeof(int)==sizeof(unsigned), "sizes do not match");
答案 1 :(得分:5)
您有两种选择:
a)C ++ 11的static_assert
b)BOOST_STATIC_ASSERT的提升
我更喜欢第一个。
修改强>
预处理器实际上并不是语言的一部分,因为名称表示它预处理文件,它不知道语言,所以它不知道sizeof
。
您可以使用一些模板来编译代码,例如:
template <typename T, bool x = sizeof(T) == 4>
class X;
template <typename T>
class X<T, true> {
T v;
const char* msg() const {
return "My size is 4";
}
}
template <typename T>
class X<T, false> {
T v;
const char* msg() const {
return "My size is NOT 4";
}
}
X<int> a;
X<short> b;
答案 2 :(得分:3)
如果您不能使用C ++ 11或Boost,那么您可能会觉得这很有用:
template <typename A, typename B>
struct MustBeSameSize {
int c[sizeof(A)-sizeof(B)];
int d[sizeof(B)-sizeof(A)];
};
template struct MustBeSameSize<int, int>;
只有当sizeof
两种类型相同时才会编译。如果他们是这样的:
template struct MustBeSameSize<char, int>;
然后你会得到一个编译类型的错误,但它不会是一个非常可读的错误;也许像(g ++ 4.4.3):
error: overflow in array dimension
这是有效的,因为任何现代编译器都应该允许零长度数组,但不允许负长度数组。
这对我有用,我认为G ++已经允许零长度数组一段时间了。但我不确定这是多么便携。 C99允许灵活的阵列成员(即未指定的大小),但我不认为这是直接相关的。简而言之,如果您需要可移植的东西,请使用C ++ 11或使用Boost。
答案 3 :(得分:3)
您可以像这样定义编译时断言宏:
#define COMPILE_TIME_ASSERT( x ) \
switch ( x ) \
{ \
case false: \
break; \
case ( x ): \
break; \
}
如果表达式为false,则会出现重复的大小写标签错误。
答案 4 :(得分:-3)
在编译时,编译器无法通过编译器找到数据类型大小不匹配或任何const变量绑定检查,因为在编译之前会对处理器前指令执行操作。因此,即使您可以检测到不匹配,也无法将其作为编译器错误抛出。但是assert()等可以帮助运行时检测 PS:我之前给出的答案与普通的x86编译器无关(但与ARM编译器一起使用)。