根据this question的答案,以下代码是合法的:
#define three 3
#define nine three*3
int main()
{
std::cout << nine;
return 0;
}
当然,它编译并运行良好。但是,上述问题的答案还指出,应该注意这些#define
指令的顺序,并且应该在它们之前定义将在其他#define
中使用的指令。但是以下代码:
#define nine three*3
#define three 3
int main()
{
std::cout << nine;
return 0;
}
同样编译并运行正常,并打印“9”。
我的编译器是否让我轻松,或者使用其他#define
的#defines确实无关紧要?编译是否会在一个更复杂的项目中失败?
值得一提的是,上面提到的问题是 C ,而我的代码是C ++。这是(假设的)行为差异的来源吗?
答案 0 :(得分:8)
three
宏之前定义 nine
宏。
您甚至可以在每次使用three
之前更改nine
:
#define nine three*3
#define three 3
int main()
{
std::cout << nine; //9
#undef three
#define three 4
std::cout << nine; //12
#undef three
//no `three` macro defined here
int three = 2;
std::cout << nine; //three * 3 == 6
return 0;
}
答案 1 :(得分:3)
预处理器执行多次运行,只有在未找到所有定义的其他定义时才结束。因此,您的代码示例都可以工作,但预处理器需要再运行一次,如果是第二个。你必须小心递归定义。然后ppc永远不会退出。
答案 2 :(得分:3)
此步骤将在预处理器步骤中完成,所有文字都将替换为其值。如果我们使用选项编译,则可以验证这一点:
$ g ++ -save-temps basic.cpp -o out
这是预处理器步骤(basic.ii文件)之后的输出:
int main()
{
std::cout << 3*3;
return 0;
}
为您的示例程序。所以顺序不应该是重要的,因为它是一种查找和替换,并且在实际编译程序之前完成。
答案 3 :(得分:0)
实际上这是因为两步解析器。在第一步中,它尝试解析所有符号,并在第二步中放置实际值。