一个C++程序编译失败引发的思考

      昨天同事写一程序,里面一行std::map<int,std::map<int,std::string>> oFuzzyMap;报错,而改成std::map<int,std::map<int,std::string> > oFuzzyMap;让他很迷惑。为什么一定要在右边的">"中间加空格才行呢。

     

      其实,且不说《C++ primer》里面有提到这点,其实从编译的角度来说,是必然会引发问题,导致编译不通过的。

     因为编译时,词法分析的时候,会遵从贪心法则,就是扫描器尽量往前扫描,直到遇到一个不能和前面字符组成词为止。也就是说,">>"可以当成一个词(右移操作符),就不会将">>"当成两个词。

     而词法分析时">>"被当成一个右移操作符,在语法分析阶段,就会找不到与前面的"<"号相匹配的词,从而引发编译错误。

 

     同事问,那为什么在词法分析时"<>"不能被配对成一个词呢?其实且不说词法分析是顺序扫描,中间有其他字符,会将这两个隔成两个词。"<"与">"跟其他括号一样,必须是两个词法单元,才能在语法分析时被配对。而且,"<"与">"在语法分析时,还具有不同的优先级关系。是不能被配对成一个词法单元的。

 

又想起去年看到过的一个C++程序:

 

这个程序编译后运行,结果是什么呢?

初看时会让人纠结,编译运行后,得到结果:

可是这又为什么呢?为什么那不是一句变量的声明语句呢?其实再从编译的角度想想,也是必然的。

 

在语义扫描时,进入一个程序块,就会产生一个对应的符号表,在编译器语义分析到main函数里面时,其符号表链是这样子的:

 

若在main函数中有语句块,又会再生成一个符号表,挂到链上去。

在分析vector<UINT4> foo;这句时,编译器以从里向外的顺序在符号表链中找各个标识符的语义信息,找到之后就开始找下一个标识符,因此,stl里面的vector就被shadow了,编译器只会认为它是一个变量。同理,UINT4也是被覆盖了。所以,那语句就被解释成operator > ( operator<(vector, UINT4), foo );

所以,像以下程序中,类型的声明是会被覆盖的,

 

结果为:

 

以前看编程的书,总说什么变量名覆盖,严谨来说,其实是标识符覆盖

如果是团队合作写代码,一定要遵循命名规范,以免因为这种标识符覆盖,写出执行起来让人莫名其妙的程序。

  

 

      当初学C++,就记住了《C++ primer》里面提到的当模板两个右尖括号在一起时,中间要加空格。就记住了,也没深究。后来痴迷过编译器,倒是没想到能够用学到的编译原理来解释这些问题。昨天被些个问题一带,自已倒是豁然开朗。

  • 0
    点赞
  • 43
    收藏
    觉得还不错? 一键收藏
  • 66
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 66
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值