编译时大小有条件

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)设置一些定义,依此类推.

  • _best_方法是使用您的构建系统(autotools等)运行检查并使用`#define SIZEOF_POINTER 4`或诸如此类的东西制作系统配置的文件,然后使用它. (4认同)
  • 值得注意的是,在C11中,`_Static_assert`将完成OP想要的. (2认同)

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().

鉴于推定的条件:

#if (sizeof(void*) <= sizeof(unsigned int)) // what goes here?
#  define POINTER_FITS_INTO_UINT
#endif
Run Code Online (Sandbox Code Playgroud)

你似乎追求的是:

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)


nmi*_*els 9

描述了如何在C中伪造编译时断言.简短版本是使用switch语句:

#define COMPILE_TIME_ASSERT(pred)            \  
    switch(0){case 0:case pred:;}
Run Code Online (Sandbox Code Playgroud)

如果pred求值为0,就像C中的假布尔表达式一样,编译器将抛出错误.


Chr*_*oph 6

假设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语言实现.


ste*_*ori 5

鉴于其他答案已经解释了为什么sizeof不能与 一起使用#if,让我为您的案例提供一个简单的解决方案(令人惊讶的是尚未提及)。看一眼

https://gcc.gnu.org/onlinedocs/cpp/Common-Predefined-Macros.html#Common-Predefined-Macros

它提到了几个预定义的__SIZEOF_XYZ__宏,它们实际上可以在预处理阶段使用,即也在#if. 假设unsigned intint大小相同,您的示例可以这样完成:

#if __SIZEOF_POINTER__ == __SIZEOF_INT__
#define POINTER_FITS_INTO_UINT
#endif
Run Code Online (Sandbox Code Playgroud)