中文注释引起代码执行错误!



------
最近遇到一个奇怪的问题,代码中的中文注释能使程序出错!!!
试看如下的代码:
int main() {
  int a = 0;
  int b = 0;

  /**停车来源字*/
  a = 10;
  b = 20;

  /**注释结束*/
  printf("a=%d\tb=%d", a, b);
   
  return 0;
}
运行的结果居然是:a=0 b=0
分析后发现中间的赋值语句被当成了注释,忽略掉了。
请问各位大虾,是否遇到此现象?怎么解释?怎么避免此现象?
编译环境是VC++6.0。
------
应该不会才对,可以试试将源文件保存成utf或者unicode格式。
------
补充一下,只有/**停车来源字*/会产生错误,在中间加空格就不会出错了。真的很诡异的现象。盼各位大虾伸出援手啊!谢谢了!

------
请验证一下,我的同事和我已经验证过了,真的如此!我们很迷茫!
------
不可能。rebuild all试试。
把注释去掉就正常?
------
我试试
------
确实有意思。
我只写这几句;
int a = 0;
int b = 0;

/**停车来源字*/
a = 10;
b = 20;

编译居然提示 fatal error C1071: unexpected end of file found in comment
将注释改为:
/**停车来源字**/ 或 /*停车来源字*/时,编译通过。
------
嗯!我这是从产品代码中提取的片断,编译能通过,运行没有问题,就是结果和期望的不一样。最终从一大堆代码中找到了这几个中文注释有问题。现在很迷茫,因为不知道其他的汉字注释会不会有类似的问题。请大虾帮帮忙啊!
------
引用 7 楼 bailingke 的回复:
嗯!我这是从产品代码中提取的片断,编译能通过,运行没有问题,就是结果和期望的不一样。最终从一大堆代码中找到了这几个中文注释有问题。现在很迷茫,因为不知道其他的汉字注释会不会有类似的问题。请大虾帮帮忙啊!

------
从规律来看,出现问题的条件:
1.注释是中文,用英文则没有问题
2.用/**/,用//无问题
3./*之后还有*,而*/前没有*
所以你保持中文注释前后的*数量相等就没有问题。哈哈
------
确实在vc6中会出错,不过在vs2005没事
------
很重要的一个发现......
debug和release版本都有问题吗?
------
有意思,注释中,只要不是全部中文就没有问题。
------
是debug版本,刚发现的怪现象啊!这月的任务完不成了,被boss扣钱了啊!
------
够诡异...
------
诡异啊
------
因为程序代码的中文注释比较普遍,全部查一遍有困难的。是否只有换编译器一条路可走了吗?还有没有别的解决方案啊?谢谢各位的参与啊
------
int main() {
int a = 0;
int b = 0;

/**停车来源字*/
a = 10;
b = 20;

**注释结束*/
printf("a=%d\tb=%d", a, b);

return 0;
}

和红色的那段注释有关系哟,和第一个注释没关系
------
不要用VC6啦,太多bug……
先试试批量替换一下注释,将/***/替换成/**/
------
int main() {
int a = 0;
int b = 0;

/**停车来源字*/
a = 10;
b = 20;

/**注释结束*/
printf("a=%d\tb=%d", a, b);

return 0;
}

和红色的那段注释有关系哟,和第一个注释没关系

终于写对了
------
可我测试的结果是加了第一段注释后,编译就通不过了。
------
ydyn1988,知道这段注释为什么出问题吗?机理是什么呀?
------
BTW:不同编译器的“最佳猜测”的算法可能不一样,因此不同编译器测试效果也可能是不同的
------
其实楼主要改也很容易。全文replace("/*","/* ")就可以了。
------
任意编译器在使用MCBS时都可能出这种问题,但是这种问题出现的概率确实很少,只有一个编码序列在多个代码集同时有含义才出现
引用 8 楼 oyljerry 的回复:
引用 7 楼 bailingke 的回复:

记得当初vc6对于中文注释支持不是很好,容易出问题

------
arong1234(阿荣) 
讲得很有道理,能说通。
------
好,明天试试,希望能解决问题。
------
引用 27 楼 bailingke 的回复:
arong1234(阿荣)
讲得很有道理,能说通。

------
这应该是在多字节编码方式下分析字符出现的问题
首先需要明确的是:Cpp文件是无法指定编码方式的,因此为了知道编码方式,编译器只能采取一种“猜测”算法,也就是看给定的文本中,这个字符最佳匹配到那种编码,就认为它是最佳匹配。

对于楼主给出的文字,我估计其二进制字节序列既可以解释为GB2312你看到的这个字符串,同时也可以解释为其他编码中的字符串,而在那个编码方式中,匹配后正好把序列中的*或者/吃掉了,导致注释被曲解。

这段话我觉得能解释我们遇到的问题,但更详细的分析得翻书了。或者由这个方面的专家给指点一下。
------
我已经说了,只有特定序列碰巧使得它“最佳匹配算法”误判才行,你加入任何一个字符,就改变了序列,最佳匹配算法就不错了,当然就没问题了。
例如,如果“字*/”导致*被吃掉,如果你写成“字 */”,它就吃不掉了,如果你改成“字**/”,则即使吃掉第一个*,第二个*还是结束了注释

引用 29 楼 happyparrot 的回复:
引用 27 楼 bailingke 的回复:
arong1234(阿荣)
讲得很有道理,能说通。

我觉得解释不通。在这段中文的任何地方插入一个英文或者其它非中文字符都没有问题,包括最后用**/结尾,这如何解释呢

------
由于这种问题出现概率这么少,你找到资料或者高手指导你的可能性都比较少。如果一定要找,建议你找“邮件乱码”或者“邮件标题乱码”之类的资料看看,希望你能看懂
引用 30 楼 bailingke 的回复:
这应该是在多字节编码方式下分析字符出现的问题
首先需要明确的是:Cpp文件是无法指定编码方式的,因此为了知道编码方式,编译器只能采取一种“猜测”算法,也就是看给定的文本中,这个字符最佳匹配到那种编码,就认为它是最佳匹配。

对于楼主给出的文字,我估计其二进制字节序列既可以解释为GB2312你看到的这个字符串,同时也可以解释为其他编码中的字符串,而在那个编码方式中,匹配后正好把序列中的*或者/……

------
以前曾经说过
“停”字编码有点问题

新建记事本,输入 “停” 字,保存关闭,重新打开,就会乱码
------
我的疑惑还在于,注释不能用中文的话,确实比较郁闷。如果用了中文,会不会还有什么别的特定序列能导致代码出错?在中文注释前后加空格是否能彻底、完全地解决此问题?
------
stjay的说法已经被我验证属实了,确实很诡异啊!
------
不是告诉你了么,只要你确保在/* 后和 */前多加几个空格或者*一般出问题可能就很少了
例如:

/**** 我的中文注释 ****/

个人观点,搞编程的英文不好是很没前途的,不为解决这个问题,你也要把英文学好
引用 34 楼 bailingke 的回复:
我的疑惑还在于,注释不能用中文的话,确实比较郁闷。如果用了中文,会不会还有什么别的特定序列能导致代码出错?在中文注释前后加空格是否能彻底、完全地解决此问题?

------
很正常,因为你只有2个字节,只要两个字节在两个编码集合中都有定义,notepad一定不知道哪个是最佳的。你看着乱码,另外一个同样定义了这个编码序列的系统(如韩文系统)也许就说这个notepad工作很正常。这是为什么我们更应该推广unicode:)
引用 33 楼 stjay 的回复:
以前曾经说过
“停”字编码有点问题

新建记事本,输入 “停” 字,保存关闭,重新打开,就会乱码

------
明白了,以前看到过这种注释风格,以为只是使代码清晰,没有别的用意。现在看起来,也是很精妙的用法。感谢各位,特别是arong1234,晚了,兄弟我先去睡了!
------
*停 也是乱码
------
其他大部分单个汉字都不乱码
等高手解答
------
晕倒,我37楼不是解释了么,停的编码肯定在两个或者更多的编码集合中定义了,notepad无法知道它到底属于哪个编码集合,因此选了某个它认为的最优集合,而哪个集合在中文系统上看就是乱码
引用 40 楼 stjay 的回复:
其他大部分单个汉字都不乱码
等高手解答

------
你用"*停"来测试说明你还是不明白我说的东西,你必须用一个序列迫使notepad认识导正确的代码集,试试在停前后加个中文也许就可以避免了

------
其实就是编码识别问题,在记事本里写“联通”保存后再打开也是显示不了。
可以试试用UltraEdit等二进制编辑软件在文件前面添加FF FE然后再试试。
------
notepad支持save as unicode
引用 43 楼 jingzhongrong 的回复:
其实就是编码识别问题,在记事本里写“联通”保存后再打开也是显示不了。
可以试试用UltraEdit等二进制编辑软件在文件前面添加FF FE然后再试试。

------
/* */是C语言的注释写法,C++就应该用//,才是标准的。
干脆制定公司编程规范,代码中不得使用/* */。
------
也不用废弃吧。其实/**/最好这么用
/*
你好
*/
与注释内容不要在同一样。
------
学习.....
------
哎呀!还有这种问题呀,这要是今天不看了这贴子,以后出现这种莫明其妙的问题,那真是会死不少脑细胞!

------
使用/** 应该会出现这样的问题~
------
学习了。
------
这个问题我们都是猜测啊,有没有官方的解释呢。。。
------
那就是在二进制转换的时候出现的问题?确实挺有意思的
------
头一次看到注释也能编译错误,开眼界
------
学习了,没遇到过
------
~~~~~~~~~~~~~
------
以前没用过这个,学习学习
------
第一次看到这种情况,但果然是真的,太神奇了
------
我看也不错....
------
“停”字的Unicode码0x505C,GBK码0xCDA3,UTF8码0xE5819C
注意其Unicode码0x505C如果当ASCII码来解释就是P\

而\既是C语言的转义符,又是C语言的续行符!

估计这才是把编译器搞晕的根本原因。

不过话说回来,这个世界上现在还不存在没有Bug的编译器,估计将来也不会有。
我们所能做的就是想办法绕过这些编译器Bug导致问题。

------
引用楼主 bailingke 的回复:
最近遇到一个奇怪的问题,代码中的中文注释能使程序出错!!!
试看如下的代码:
int main() {
int a = 0;
int b = 0;

/**停车来源字*/
a = 10;
b = 20;

/**注释结束*/
printf("a=%d\tb=%d", a, b);

return 0;
}
运行的结果居然是:a=0 b=0
分析后发现中间的赋值语句被……

------
经鉴定,编码格式问题
------
多了个星号
------
学习了。。。
------
确实是需要注意的问题.

我用的是 Microsoft Visual Studio 2008, 没问题。
------
/**注释结束*/
试了一下,如果/*和*/之间的注释字节是偶数的话,就没有问题的,就拿上面的来说,4个汉字加一个*字符,结果是是奇数,如果在他们之间任意加个字符,如果总和能够保持偶数的话,就不会出现编译错误的。
------
编译器的问题,Visual Studio 不能设置任意的源文件编码格式,从别的集成环境移植过来容易出现这个问题。
可以先转换格式成unicode,再倒入;或者去掉注释,倒入再加上注释
------
还真有问题,将注释开头处星号只留一个就可以了
------
关注!!!!!
------
哦 bug?》?
------
LZ的系统、vc各是什么语言的版本?
------
居然还有这种事。。。
------
楼主长得像胡爷爷
------
居然。。。。。。。。。
------
没见过!!!!!!!!!
------
学习一下。。。
------
见识了
------
有意思的问题
mark
------
[Quote=引用 73 楼 hai00jiao 的回复:]
楼主长得像胡爷爷
[/Quo
你太有才了。。。这都被你发现了。。。我也觉得像,一直在纳闷,这么多人回帖,怎么就没人发现。
------
关注!!!!!
------
应该是VC6.0的一个bug吧,批注释的前后星号不等。。。。
------
其实vc6奇怪的bug还有很多的,只不过你没发现而已,
例如我以前遇到过变量声明的顺序影响结果的情况,
例如:
Class Class1;
Class Class2;
-〉这样就会出bug
Class Class2;
Class Class1;
-〉就不会。


------
引用 79 楼 juanmaolang 的回复:

[Quote=引用 73 楼 hai00jiao 的回复:]
楼主长得像胡爷爷
[/Quo
你太有才了。。。这都被你发现了。。。我也觉得像,一直在纳闷,这么多人回帖,怎么就没人发现。

------
关注













.
------
牛X~
------
引用 66 楼 visualeleven 的回复:
/**注释结束*/
试了一下,如果/*和*/之间的注释字节是偶数的话,就没有问题的,就拿上面的来说,4个汉字加一个*字符,结果是是奇数,如果在他们之间任意加个字符,如果总和能够保持偶数的话,就不会出现编译错误的。

------
6楼说得很正确
另外,在使用 /**/嵌套 /**/很容易出现这种问题
建议:当代码段很长,且里面有中文注释 /**/时,要屏蔽某些代码,可以采用
#ifdef 
#endif
的方式来做
------
联通二字在新建文本里也会出现乱码~


------
学习了,经验啊!!
------
引用 88 楼 chenyu2202863 的回复:
联通二字在新建文本里也会出现乱码~

------
应该不会才对,可以试试将源文件保存成utf或者unicode格式。
------
呵呵~~看来是很诡异~~~
------
要按编程规范来,/*就可以了,不要/**,汉字会引起怪异的问题,尤其字符集设置不正确时
------
vc6确实比较落后,都不支持uft-8的代码

不过我没这种注释习惯,函数里面一般用 //
用这个的话,应该就没问题了
------
只要将注释符号的前后各加一个空格 即可解决此类问题:
如:
/** 停车来源字 */

请参阅:
Fatal Error C1071
unexpected end of file found in comment

The compiler reached the end of the file while scanning a comment.

Possible causes

Missing comment terminator (*/).
Missing newline character after a comment on the last line of a source file.
The following sample generates C1071:

 // C1071.cpp
int main() {
}

/* this comment is fine */
/* forgot the closing tag // C1071
------
引用 37 楼 arong1234 的回复:
很正常,因为你只有2个字节,只要两个字节在两个编码集合中都有定义,notepad一定不知道哪个是最佳的。你看着乱码,另外一个同样定义了这个编码序列的系统(如韩文系统)也许就说这个notepad工作很正常。这是为什么我们更应该推广unicode:)

引用 33 楼 stjay 的回复:
以前曾经说过
“停”字编码有点问题

新建记事本,输入 “停” 字,保存关闭,重新打开,就会乱码
……

------
我测试了下,如果用到/**则系统会在里面找**/与他匹配(两个*),直接会忽略一个(*)的.如果找不到两个*就会报错。但是/***(则不需要***/)来匹配。看来VC6.0真的还有问题咧。
------
顶顶顶顶顶顶顶顶顶顶顶顶
------
可能是注释符的问题吧. 
 我一般都用 /*注释内容*/  
 没见过你说的情况 ..
------
没看明白
桂ICP备07017180号