我正在学习c ++,宏观行为并不像预期的那样。
1 #include<cstdlib>
2 #include<iostream>
3 #include<cstring>
4 #define die(x) std::cout << x << std::endl ; exit(-1)
5 const char *help = "Usage: coffee --help --version";
6 const char *version = "alpha";
7 int main(int argc,char **argv)
8 {
9 if(argc<2||!strcmp(argv[1],"--help"))
10 die(help);
11 if(!strcmp(argv[1],"--version"))
12 die(version);
13
14 return 0;
15
16 }
g++ -o sample ./*
./sample --help
输出:用法:coffee --help --version
./sample --version
输出:
我很困惑为什么--version
没有输出字符串alpha
。
答案 0 :(得分:6)
当这两行中的宏预处理器扩展std::cout << x << std::endl ; exit(-1)
时
9 if(argc<2||!strcmp(argv[1],"--help"))
10 die(help);
结果代码是:
if(argc<2||!strcmp(argv[1],"--help"))
std::cout << help << std::endl;
exit(-1);
这可能不是你想要的;
“多语句宏”的常见技巧是在宏中使用do { ... } while(0)
语句。
您可以使用gcc -E
或cl -E
从C预处理器获取输出,这样您就可以看到编译器实际看到的内容。
编辑:我应该指出,在这种情况下,我个人更喜欢“死(msg)函数”而不是修复宏。然后,你可以,例如,在die()中设置一个breakpoing,并找出当某些东西不正常时你是如何到达那里的!您无法在宏中设置断点。
答案 1 :(得分:0)
试着粗暴地替换宏的主体,你会明白为什么:
if(argc<2||!strcmp(argv[1],"--help"))
die(help);
变为:
if(argc<2||!strcmp(argv[1],"--help"))
std::cout << help << std::endl;
exit(-1);
对于{ }
语句没有大括号if
,正文仅由一条指令构成,因此始终执行exit(-1)
。
你会发现,如果使用if / else if
而不是if / if
夫妇,那么因为第二个else if
错过了它的父亲。
答案 2 :(得分:0)
你忘记了{ }
。手动展开宏,您将看到结果:
if(argc<2||!strcmp(argv[1],"--help"))
std::cout << help << std::endl ; exit(-1);
即
if(argc<2||!strcmp(argv[1],"--help"))
std::cout << help << std::endl ;
exit(-1);
答案 3 :(得分:0)
替换宏后的代码
if(argc<2||!strcmp(argv[1],"--help"))
std::cout << help << std::endl ; exit(-1) ; //<-- this exit will work always.
if(!strcmp(argv[1],"--version"))
std::cout << version << std::endl ; exit(-1) ;
正确的方法:
#define die(x) do {std::cout << x << std::endl ; exit(-1); } while(false);