基于sizeof运算符的编译时断言
Compile time assertion based on sizeof operator
鉴于 sizeof()
运算符是一个编译时运算符(来自 this Whosebug 接受的答案),我试图继续并基于它实施编译时类型检查。
我想实现的是编译时检查参数是否为字符数组,如果不是,则引发编译错误。我的解决方案基于字符占用一个字节这一事实。所以我想到了这个:
#define assert(maybeStr)\
extern int varaible_not_exist;\
if (sizeof(maybeStr[0]) != 1)\
{\
varaible_not_exist++;\
}
我发现如果 sizeof(maybeStr[0])
在编译时求值,那么整个 if
都可以在编译时求值,这意味着如果 if
语句是false(maybeStr
确实是字符数组)在编译时,varaible_not_exist++
最终不会被编译,也不会出现编译错误。反之亦然,如果 if
语句为真(maybeStr
不是字符数组)那么 varaible_not_exist++
将被编译并引发编译错误。
长话短说,它似乎起作用了。我目前只在 online-c-compiler 中测试过它,但这个宏似乎可以完成这项工作。
现在,我的问题是这个宏是否可靠?我的意思是有没有可能不同的编译器和不同的优化标志会产生不同的结果?
I mean is it possible that different compilers and different optimizations flags will yield different result?
是的,这是可能的。您的代码不可靠。
如果您的编译器支持 C11,您可以使用 static assertion 代替:
#include <assert.h>
...
static_assert(sizeof(maybeStr[0]) == 1, "parameter must be a string");
鉴于 sizeof()
运算符是一个编译时运算符(来自 this Whosebug 接受的答案),我试图继续并基于它实施编译时类型检查。
我想实现的是编译时检查参数是否为字符数组,如果不是,则引发编译错误。我的解决方案基于字符占用一个字节这一事实。所以我想到了这个:
#define assert(maybeStr)\
extern int varaible_not_exist;\
if (sizeof(maybeStr[0]) != 1)\
{\
varaible_not_exist++;\
}
我发现如果 sizeof(maybeStr[0])
在编译时求值,那么整个 if
都可以在编译时求值,这意味着如果 if
语句是false(maybeStr
确实是字符数组)在编译时,varaible_not_exist++
最终不会被编译,也不会出现编译错误。反之亦然,如果 if
语句为真(maybeStr
不是字符数组)那么 varaible_not_exist++
将被编译并引发编译错误。
长话短说,它似乎起作用了。我目前只在 online-c-compiler 中测试过它,但这个宏似乎可以完成这项工作。
现在,我的问题是这个宏是否可靠?我的意思是有没有可能不同的编译器和不同的优化标志会产生不同的结果?
I mean is it possible that different compilers and different optimizations flags will yield different result?
是的,这是可能的。您的代码不可靠。
如果您的编译器支持 C11,您可以使用 static assertion 代替:
#include <assert.h>
...
static_assert(sizeof(maybeStr[0]) == 1, "parameter must be a string");