是否可以从头文件输出变量?

Is it possible to output a variable from a header file?

假设我有一个包含如下行的头文件:

#if LONG_BIT != 8 * SIZEOF_LONG
/* 04-Oct-2000 LONG_BIT is apparently (mis)defined as 64 on some recent
 * 32-bit platforms using gcc.  We try to catch that here at compile-time
 * rather than waiting for integer multiplication to trigger bogus
 * overflows.
 */
#error "pp897:  LONG_BIT  definition appears wrong for platform (bad gcc/glibc config?)."
#endif

我想输出LONG_BIT和SIZEOF_LONG的值。是否可以这样做,或者从头文件中是不可能的?

在这种情况下,您需要测试一些值。您可以像 switch/case 语句一样一个一个地测试看似合理的语句,以防万一。

独立示例。前 2 个 define 语句在这里用于测试,从最终代码中删除

// completely bogus/incoherent values just to test
#define LONG_BIT 32
#define SIZEOF_LONG 4444

// operational test from now on    
#if LONG_BIT != 8 * SIZEOF_LONG
#if LONG_BIT == 32
#error "pp897:  LONG_BIT  definition appears wrong for platform (bad gcc/glibc config?): size 32"
#elif LONG_BIT == 64
#error "pp897:  LONG_BIT  definition appears wrong for platform (bad gcc/glibc config?): size 64"
#else
#error "pp897:  LONG_BIT  definition appears wrong for platform (bad gcc/glibc config?): size ???"
#endif
#endif

编译输出:

test.c:7:2: error: #error "pp897:  LONG_BIT  definition appears wrong for platfo
rm (bad gcc/glibc config?): size 32"

此方法兼容包括 C89 在内的所有标准

C 中的

_Static_assert 或 C++ 中的 static_assert 可以测试条件并显示字符串,并且可以使用预处理器扩展构造字符串:

#define LONG_BIT    64
#define SIZEOF_LONG 4

#define StringizeHelper(x)  #x
#define Stringize(x)        StringizeHelper(x)

_Static_assert(LONG_BIT == 8 * SIZEOF_LONG,
    "LONG_BIT is " Stringize(LONG_BIT) " but must be 8 * "
    Stringize(SIZEOF_LONG) ".");

用 Clang 输出:

x.c:7:1: error: static_assert failed "LONG_BIT is 64 but must be 8 * 4."
_Static_assert(LONG_BIT == 8 * SIZEOF_LONG,
^              ~~~~~~~~~~~~~~~~~~~~~~~~~~~
1 error generated.

使用 GCC 或 Clang(至少),您可以打印出预处理器宏的值:

#define LONG_BIT 60
#pragma message "LONG_BIT is " STRINGIFY(LONG_BIT)

但这不会让您得到 sizeof(long) 的值,它不是预处理器构造。它也不会做算术; LONG_BIT 需要是一个实际数字才能生成所需的消息。

这不适用于 #error,后者不在文本中进行宏替换。

这里,STRINGIFY有通常的two-stage定义:

#define STRINGIFY_(x) #x
#define STRINGIFY(x) STRINGIFY_(x)

您也可以将整个消息写在参数中,至少在这种情况下是这样,但要注意意外的扩展:

#pragma message STRINGIFY(LONG BIT is LONG_BIT)