ST3*_*ST3 20 c c++ c-preprocessor preprocessor-directive
我一直在寻找代码高尔夫,并有一个想法尝试这个代码:
#define D #define 添加此行后,一切正常,但我将其扩展为:
#define D #define
D VALUE
Run Code Online (Sandbox Code Playgroud)
在这里我得到了5个编译错误.如果我D改成#define一切都很好,有人可以解释一下,为什么这段代码是非法的?
注意: 我使用的是VS2008编译器.
编辑: 经过一些答案,我看到我需要给出编译错误列表:
第一个错误显示D不仅是define,还包括#.
Eri*_*hil 31
C 2011(N1570)6.10.3.4 3:"得到的完全宏替换的预处理标记序列不会被处理为预处理指令,即使它类似于一个......"
C++ 2010(N3092)16.3.4 [cpp.rescan] 3具有完全相同的文本.
Car*_*rum 10
看起来您的预处理器正在进行您想要的替换,但您可能无法获得所需的行为 - 预处理器通常只是单个传递操作.示例(使用clang,但您应该能够使用适当的VS2008标志重现):
$ cat example.c
#define D #define
D VALUE
$ cc -P -E example.c
#define VALUE
Run Code Online (Sandbox Code Playgroud)
这#define VALUE将直接进入编译器,编译器将不知道如何处理它 - 毕竟它是一个预处理器指令.Clang的错误,供参考,与您的相似:
$ cc -c example.c
example.c:2:1: error: expected identifier or '('
D VALUE
^
example.c:1:11: note: expanded from macro 'D'
#define D #define
^
1 error generated.
Run Code Online (Sandbox Code Playgroud)
AnT*_*AnT 10
此代码是非法的,因为语言规范说它是非法的.根据C和C++预处理器规范,使用预处理器构建的任何代码都不会被解释为另一个预处理器指令.简而言之,您无法使用预处理器构建预处理程序指令.期.
(另外,您无法使用预处理器构建注释.)
这是行不通的,因为预处理是在一次通过中执行的.例如,考虑下一个代码:
#define MYDEFINEWEIRD #define
MYDEFINEWEIRD N 6
int main() {
return 0;
}
Run Code Online (Sandbox Code Playgroud)
预处理后,您的代码将如下所示:
#define N 6
int main() {
return 0;
}
Run Code Online (Sandbox Code Playgroud)
和"#define"不是C或C++上的有效语法.此外,由于不会处理生成的预处理程序指令,因此它不会解析代码中对"N"宏的后续引用.
只是为了好玩,您可以使用g ++/gcc从命令行调用预处理器两次.考虑下一个代码(define.cpp):
#include <iostream>
#define MYDEFINEWEIRD #define
MYDEFINEWEIRD N 6
using namespace std;
int main() {
cout << N << endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
然后你可以这样做:
$ g++ -E define.cpp | g++ -o define -x c++ - && ./define
Run Code Online (Sandbox Code Playgroud)
并将输出:
6
Run Code Online (Sandbox Code Playgroud)