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

时间:2019-05-09 19:35:49

标签: c c-preprocessor

假设我有一个带有这样的行的头文件:

#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的值。可以这样做,还是从头文件中做到这一点呢?

3 个答案:

答案 0 :(得分:3)

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.

答案 1 :(得分:1)

在这种情况下,您需要测试一些值。您可以像switch / case语句一样对可能的选项进行逐一测试,以防万一。

独立示例。前两个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在内的所有标准兼容

答案 2 :(得分:0)

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

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

但这不会为您提供sizeof(long)的值,它不是预处理程序的构造。它也不做算术; LONG_BIT必须是实际数字,以便产生所需的消息。

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

在这里,STRINGIFY具有通常的两阶段定义:

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

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

#pragma message STRINGIFY(LONG BIT is LONG_BIT)