VS2010 C ++预处理器和嵌套括号

时间:2015-01-29 17:02:27

标签: c++ visual-studio-2010 nested c-preprocessor parentheses

我使用VS2010 C ++中的预处理器定义版本字符串。我有以下#defines:

#define IMPORT_VERSION_1_1                      L"IMPORT 1.0"
#define EPAPI_VERSION_1_1                       L"EPAPI 1.1"
#define EPAPI_VERSION_1_2                       L"EPAPI 1.2"
#define EPAPI_VERSION_1_3                       L"EPAPI 1.3"
#define EPAPI_VERSION_ALL_1_2                   (EPAPI_VERSION_1_2 L"," EPAPI_VERSION_1_3)
#define EPAPI_VERSION_ALL_1_2_NoParens          EPAPI_VERSION_1_2 L"," EPAPI_VERSION_1_3
#define EPAPI_VERSION_ALL_1_3                   (EPAPI_VERSION_1_3)

#define Broken                                  (EPAPI_VERSION_ALL_1_2          L"," IMPORT_VERSION_1_1)
#define Works                                   (EPAPI_VERSION_ALL_1_2_NoParens L"," IMPORT_VERSION_1_1)

const wchar_t* sJunk = Broken;

如果我使用Broken来初始化sJunk,我会收到以下错误:

  

错误C2143:语法错误:缺少')'之前'字符串
  错误C2059:语法错误:')'

如果我使用Works,没有错误,我得到了我希望的字符串: EPAPI 1.2,EPAPI 1.3,IMPORT 1.0

显然这与EPAPI_VERSION_ALL_1_2的嵌套括号有关。但是,如果我可以避免它,我真的不想删除它们,因为对非括号内的宏的副作用已有详细记录。

任何人都可以提供有关如何定义我想要的宏并保留parens的任何建议吗?

谢谢

1 个答案:

答案 0 :(得分:0)

结果复杂的一个简单原因。让我们解决所有宏:

Broken
(EPAPI_VERSION_ALL_1_2 L"," IMPORT_VERSION_1_1)
((EPAPI_VERSION_1_2 L"," EPAPI_VERSION_1_3) L"," L"EPAPI 1.1")
((L"EPAPI 1.2" L"," L"EPAPI 1.3") L"," L"EPAPI 1.1")

您的代码取决于两个字符串文字相互跟随的事实。这意味着我们可以简化:

((L"EPAPI 1.2,EPAPI 1.3") L",EPAPI 1.1")

现在,只剩下两个字符串文字 - 但它们不是直接相邻的!

相反,你有任何旧的表达式(你知道,带括号的东西)紧接着是一个字符串。编译器宁愿您使用运算符跟踪它,或者 - 甚至更好 - 只需关闭另一个括号。这就是编译器消息的来源,它需要)

建议的解决方案:

#define EPAPI_VERSION_ALL_1_2 (EPAPI_VERSION_ALL_1_2_NoParens)

P.S。:由于这种字符串文字连接发生在Lexer中,这实际上很难为编译器构建器解决;)