【问题标题】:Is it possible to output a variable from a header file?是否可以从头文件中输出变量?
【发布时间】:2019-09-27 16:53:57
【问题描述】:

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

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

【问题讨论】:

  • 不,它们不是变量,而是常量。但是,您仍然可以使用 std::cout 输出它们
  • @Lehks 添加这只是给了我:/awips2/python/include/python2.7/pyport.h:900:1:错误:命名空间“std”中的“cout”没有命名类型std::cout
  • @EricPostpischil 那么预处理器宏可以输出还是不能输出?

标签: c c-preprocessor


【解决方案1】:

在这种情况下,您需要测试一些值。您可以像 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

【讨论】:

  • 看来,通过重新定义一个值,编译器会说出它的值是什么:警告:“SIZEOF_LONG”重新定义[默认启用]#define SIZEOF_LONG 4444 ^ 在来自/acme/python/ 的文件中include/python2.7/Python.h:8:0, from edex_HWR_sfc.C:44: /acme/python/include/python2.7/pyconfig.h:1051:0: 注意:这是前面定义的位置#define SIZEOF_LONG 8
  • 当然,我确实重新定义它只是为了测试,因为评论指出“// 完全虚假的值只是为了测试”
  • 不知道你为什么要重申这一点。我的评论中似乎没有任何提示。
  • 好的,那么如果你想重新定义一个值,你必须先#undef它。
  • 谢谢。我的意思是,通过尝试重新定义它,问题就解决了——尝试导致 gcc 在它的警告中显示我正在寻找的值!
【解决方案2】:

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:错误:static_assert 失败“LONG_BIT 是 64,但必须是 8 * 4。” _Static_assert(LONG_BIT == 8 * SIZEOF_LONG, ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 产生 1 个错误。

【讨论】:

  • 复制并粘贴了您的代码。使用 gcc 我得到:/awips2/python/include/python2.7/pyport.h:897:15: error: expected constructor, destructor, or type conversion before '(' token _Static_assert(LONG_BIT == 8 * SIZEOF_LONG,跨度>
  • @Tharpa 你是在C 还是C++ 编译?
  • @Bob__,查看Makefile,它有一行C++_FLAGS += -fexceptions,所以我猜是C++。
【解决方案3】:

使用 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)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-10-15
    • 2018-05-15
    • 1970-01-01
    • 2022-01-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-12
    相关资源
    最近更新 更多