是否可以从头文件输出变量?
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)
假设我有一个包含如下行的头文件:
#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 在内的所有标准
_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)