【问题标题】:Macro that swallows semicolon outside of function在函数之外吞下分号的宏
【发布时间】:2014-10-16 04:07:31
【问题描述】:

是否有任何成语强制在函数外部的 cpp 宏之后使用分号?

在函数内部使用宏的已知解决方案是:

#define MACRO(x) \
  do {
    x * 2;
  } while(0)

但是,假设我有一个如下所示的宏:

#define DETAIL(warning) _Pragma(#warning)
#define WARNING_DISABLE(warning) DETAIL(GCC diagnostic ignore warning)

我可以在宏中放入什么,以在该语句之后强制使用分号。该语句可以在函数内部或外部使用:

WARNING_DISABLE("-Wunused-local-typedefs")
#include "boost/filesystem.hpp"
void foo(const int x) {
    WARNING_DISABLE("-Wsome-warning")
    ...
}

是否有任何 C/C++ 语法会在没有副作用的文件中的任何位置强制解析器中的分号?

编辑:一个可能的用例:

#define MY_CPPUNIT_TEST_SUITE(test_suite_class) \
  WARNING_PUSH \
  /* the declaration of the copy assignment operator has been suppressed */ \
  INTEL_WARNING_DISABLE(2268) \
  /* the declaration of the copy assignment operator has been suppressed */ \
  INTEL_WARNING_DISABLE(2270) \
  /* the declaration of the copy constructor operator has been suppressed */ \
  INTEL_WARNING_DISABLE(2273) \
  CPPUNIT_TEST_SUITE(test_suite_class); \
  WARNING_POP \
  /* force a semi-colon */ \
  UDP_KEYSTONE_DLL_LOCAL struct __udp_keystone_cppunit_test_suite ## __LINE__ {}

【问题讨论】:

  • 我想使用的 other 示例是在为嵌入式编译时指定代码部分,这是一个编译指示,所以如果它是 CODE_SECTION(...); 那就太好了而不是CODE_SECTION(...)。显然这不是世界末日,但想知道是否有人拥有预处理器来完成此任务?
  • 我唯一能想到的就是将_Pragma(#x); typedef int __dummy_ ## __LINE__ 放在上面,但最终会出现大量关于 gcc 4.8.1 上未使用的 typedef 的警告
  • 警告可以被禁用,你知道的 ;)
  • 你的问题不是分号,是同一行当前位置后面的任何字符,我不认为一般问题可以解决。承认无法解决一般问题,只需保持原样并用宏记录它:行中不能有多余的字符。
  • @SvenS :) 我知道,如果有什么东西没有警告就好了

标签: c++ c c-preprocessor


【解决方案1】:

你不需要 LINE 技巧 - 前向声明一些结构就足够了,允许多次,不需要实际定义。与实际结构的冲突也不应该成为问题。

#define DETAIL(warning) _Pragma(#warning) struct dummy

【讨论】:

    【解决方案2】:
    #define DETAIL(warning) _Pragma(#warning) struct X ## __LINE__ {}
    

    【讨论】:

    • 您认为编译器通常会从库中优化出X[LINE] 符号吗?工作没有错误,比我的 typedef 想法更好。 +1 来自我 :)
    • @MattClarkson 我对目标文件内容知之甚少,无法回答这个问题,抱歉。
    【解决方案3】:

    最简单的是外部函数声明

    #define MACRO_END_(LINE) extern void some_inprobable_long_function_name ## LINE(void)
    #define MACRO_END MACRO_END_(__LINE__)
    

    行技巧之所以存在,是因为某些带有过多警告的编译器会在重复声明时向您发出警告。

    这个宏可以在任何允许声明的上下文中工作,所以几乎所有地方都使用 C99:

    #define DETAIL(warning) _Pragma(#warning) MACRO_END
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-06-02
      • 1970-01-01
      • 2018-02-25
      • 1970-01-01
      相关资源
      最近更新 更多