Ale*_*nov 15 c compile-time c-preprocessor
如果条件涉及sizeof为真,我想定义一个宏,如果它是假,则不做任何事情(但仍然编译).如果支持预处理器sizeof,它将如下所示:
#if (sizeof(void*) <= sizeof(unsigned int)) // what goes here?
# define POINTER_FITS_INTO_UINT
#endif
Run Code Online (Sandbox Code Playgroud)
有一些页面(例如http://scaryreasoner.wordpress.com/2009/02/28/checking-sizeof-at-compile-time/)解释如何使一个编译时断言的sizeof(和无法编译,如果它失败了),但我没有看到一种方法将这种方法扩展到我想要的.
Goz*_*Goz 14
你不能这样做.sizeof是一个编译时运算符.#if和#define以及预处理器相关.由于预处理器在编译器之前运行,因此不起作用.但是,您可以找到一个神秘的编译器开关,它允许您多次传递它(即预处理,假装编译,预处理,编译)但是,平心而论,我放弃尝试做你想要的.它并不意味着工作,简单地说,它没有.
最好的方法是将这样的定义设置为传递给编译器的-D命令.您可以静态断言所选择的是正确的.这样,您只需在外部为给定的编译模式(例如PowerPC Release)设置一些定义,依此类推.
Jon*_*ler 11
您的问题的正确解决方案是使用C99标准标头:
#include <stdint.h>
#include <inttypes.h>
Run Code Online (Sandbox Code Playgroud)
你只需要两个中的一个,因为#include <inttypes.h>包括来自的材料#include <stdint.h>; 然而,很多材料的<inttypes.h>,只有需要使用格式化的I/O相关的scanf()和printf().
鉴于推定的条件:
Run Code Online (Sandbox Code Playgroud)#if (sizeof(void*) <= sizeof(unsigned int)) // what goes here? # define POINTER_FITS_INTO_UINT #endif
你似乎追求的是:
uintptr_t
Run Code Online (Sandbox Code Playgroud)
这是无符号整数类型,足以容纳任何指针(即C标准中的任何数据指针; POSIX强加一个额外的规则,它也必须足够大以容纳函数指针).类型uintptr_t定义于<stdint.h>.
如果您随后要打印此类值或原始指针,则可以使用以下信息<inttypes.h>:
printf("Pointer = 0x%" PRIXPTR "\n", uintptr_value);
printf("Pointer = 0x%" PRIXPTR "\n", (uintptr_t)any_pointer);
Run Code Online (Sandbox Code Playgroud)
这描述了如何在C中伪造编译时断言.简短版本是使用switch语句:
#define COMPILE_TIME_ASSERT(pred) \
switch(0){case 0:case pred:;}
Run Code Online (Sandbox Code Playgroud)
如果pred求值为0,就像C中的假布尔表达式一样,编译器将抛出错误.
假设C99,你可以使用
#include <limits.h>
#include <stdint.h>
#if UINTPTR_MAX <= UINT_MAX
...
Run Code Online (Sandbox Code Playgroud)
这意味着sizeof (void *) <= sizeof (intptr_t) <= sizeof (int)任何理智的C语言实现.
鉴于其他答案已经解释了为什么sizeof不能与 一起使用#if,让我为您的案例提供一个简单的解决方案(令人惊讶的是尚未提及)。看一眼
https://gcc.gnu.org/onlinedocs/cpp/Common-Predefined-Macros.html#Common-Predefined-Macros。
它提到了几个预定义的__SIZEOF_XYZ__宏,它们实际上可以在预处理阶段使用,即也在#if. 假设unsigned int和int大小相同,您的示例可以这样完成:
#if __SIZEOF_POINTER__ == __SIZEOF_INT__
#define POINTER_FITS_INTO_UINT
#endif
Run Code Online (Sandbox Code Playgroud)