为什么这个宏会产生语法错误?

时间:2016-07-17 06:53:34

标签: c++ macros preprocessor-directive indirection

所以这是我的代码:

// Defines a tuple
#define __WINDOW__RESOLUTION__ 500, 200 

// Seperate the tuple
#define __WINDOW__X__1(Width, Height)  (Width)
#define __WINDOW__Y__1(Width, Height)  (Height)

// Add another sort of indirection because my tuple is a macro
#define __WINDOW__X__(Macro) __WINDOW__X__1(Macro)
#define __WINDOW__Y__(Macro) __WINDOW__Y__1(Macro)

// These should be the final values 500 and 200
#define __WINDOW__RESOLUTION__X__ (__WINDOW__X__(__WINDOW__RESOLUTION__))
#define __WINDOW__RESOLUTION__Y__ (__WINDOW__Y__(__WINDOW__RESOLUTION__))

当我使用第一个宏时,最终的数字应该出现问题:

std::cout << __WINDOW__RESOLUTION__X__ << std::endl; // Outputs 200 instead of 500

上面的行输出数字200,所以Y值代替X值

std::cout << __WINDOW__RESOLUTION__Y__ << std::endl; // ERR with macro underlined

这条线甚至无法编译[C2059,语法错误:&#34;)&#34; ]

感谢您帮助我Alex

2 个答案:

答案 0 :(得分:2)

使用gcc4.9编译时似乎工作正常,但问题可能在于编译器将__WINDOW__RESOLUTION__作为单个参数进行线程化。例如,如果您替换

#define __WINDOW__RESOLUTION__X__ (__WINDOW__X__(__WINDOW__RESOLUTION__))

#define __WINDOW__RESOLUTION__X__ (__WINDOW__X__(500, 200))

它会抛出错误,因为__WINDOW__X__只需要1个参数。

您可以在宏中使用...__VA_ARGS__来解决此问题,这会转发它收到的任何参数:

#define __WINDOW__X__(...) __WINDOW__X__1(__VA_ARGS__)
#define __WINDOW__Y__(...) __WINDOW__Y__1(__VA_ARGS__)

答案 1 :(得分:1)

为了记录 - 我知道你的解决方案是&#34;不要这样做&#34;,但我仍然想为原始问题提供答案。

事实上,我实际上并没有在您的代码中看到任何错误的。如果你使用像这样的基本测试示例编译它,它实际上工作正常:

// Defines a tuple
#define __WINDOW__RESOLUTION__ 500, 200 

// Seperate the tuple
#define __WINDOW__X__1(Width, Height)  (Width)
#define __WINDOW__Y__1(Width, Height)  (Height)

// Add another sort of indirection because my tuple is a macro
#define __WINDOW__X__(Macro) __WINDOW__X__1(Macro)
#define __WINDOW__Y__(Macro) __WINDOW__Y__1(Macro)

// These should be the final values 500 and 200
#define __WINDOW__RESOLUTION__X__ (__WINDOW__X__(__WINDOW__RESOLUTION__))
#define __WINDOW__RESOLUTION__Y__ (__WINDOW__Y__(__WINDOW__RESOLUTION__))

#include <iostream>
using namespace std;

int main() {
    // your code goes here
    std::cout << __WINDOW__RESOLUTION__X__ << std::endl;
    std::cout << __WINDOW__RESOLUTION__Y__ << std::endl;
    return 0;
}

看起来你的错误可能与你上一个macro中的括号有关,所以只是删除它们可能会解决这个问题,但是再一次 - 这对我来说并不是必需的(使用{{ 1 {}在gcc 5.4)下:

ubuntu

之前还指出,双重下划线// These should be the final values 500 and 200 #define __WINDOW__RESOLUTION__X__ __WINDOW__X__(__WINDOW__RESOLUTION__) #define __WINDOW__RESOLUTION__Y__ __WINDOW__Y__(__WINDOW__RESOLUTION__) 后跟一个大写字母是保留的,但它肯定没有阻止__编译这个 - 也许它会产生一个但更严格的编译标志错误!