一个C++程序编译失败引发的思考 - feellin的专栏 - CSDN博客

来源:百度文库 编辑:神马文学网 时间:2024/04/19 09:24:11
一个C++程序编译失败引发的思考 收藏
      昨天同事写一程序,里面一行std::map> oFuzzyMap;报错,而改成std::map > oFuzzyMap;让他很迷惑。为什么一定要在右边的">"中间加空格才行呢。            其实,且不说《C++ primer》里面有提到这点,其实从编译的角度来说,是必然会引发问题,导致编译不通过的。     因为编译时,词法分析的时候,会遵从贪心法则,就是扫描器尽量往前扫描,直到遇到一个不能和前面字符组成词为止。也就是说,">>"可以当成一个词(右移操作符),就不会将">>"当成两个词。     而词法分析时">>"被当成一个右移操作符,在语法分析阶段,就会找不到与前面的"<"号相匹配的词,从而引发编译错误。     同事问,那为什么在词法分析时"<>"不能被配对成一个词呢?其实且不说词法分析是顺序扫描,中间有其他字符,会将这两个隔成两个词。"<"与">"跟其他括号一样,必须是两个词法单元,才能在语法分析时被配对。而且,"<"与">"在语法分析时,还具有不同的优先级关系。是不能被配对成一个词法单元的。
又想起去年看到过的一个C++程序: 
这个程序编译后运行,结果是什么呢?初看时会让人纠结,编译运行后,得到结果: 
可是这又为什么呢?为什么那不是一句变量的声明语句呢?其实再从编译的角度想想,也是必然的。 在语义扫描时,进入一个程序块,就会产生一个对应的符号表,在编译器语义分析到main函数里面时,其符号表链是这样子的: 
若在main函数中有语句块,又会再生成一个符号表,挂到链上去。在分析vector foo;这句时,编译器以从里向外的顺序在符号表链中找各个标识符的语义信息,找到之后就开始找下一个标识符,因此,stl里面的vector就被shadow了,编译器只会认为它是一个变量。同理,UINT4也是被覆盖了。所以,那语句就被解释成operator > ( operator<(vector, UINT4), foo );所以,像以下程序中,类型的声明是会被覆盖的, 
结果为:
 以前看编程的书,总说什么变量名覆盖,严谨来说,其实是标识符覆盖。如果是团队合作写代码,一定要遵循命名规范,以免因为这种标识符覆盖,写出执行起来让人莫名其妙的程序。        当初学C++,就记住了《C++ primer》里面提到的当模板两个右尖括号在一起时,中间要加空格。就记住了,也没深究。后来痴迷过编译器,倒是没想到能够用学到的编译原理来解释这些问题。昨天被些个问题一带,自已倒是豁然开朗。 本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/feellin/archive/2010/11/26/6037612.aspx