这两个星期在调试刚接手的一个工程,从github克隆出来编译有一堆问题,如下面这样:

定位了很久,实在没有发现问题。在用beyond compare比较两个工程的时候发现在beyond compare下看到“连续采集卡”后面还有“{”,删除中文注释后,代码可以编译通过。至此发现了中文注释引起的代码编译问题。针对注释,以前在华为也有专门的规范来限制,但那时还没有什么体会,只到这次遇到这个问题,才知道规范为什么要那样规定。具体的分析可以参考下面的两个文章链接。

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

以下文字来源于原文链接:Visual Studio UTF-8编码中文注释导致的罕见问题 - 魏王天下

Windows、Linux、Mac平台下的纯文本文件,在内容仅为英文字母以及其他ASCII编码能表达的字符的情况下,文本一律为ASCII编码。

当然内容包含中文等非ASCII字符时,Windows下默认使用ISO 8859-1编码,而Linux和Mac平台则默认使用UTF-8编码。

ISO编码的文件在Linux和Mac平台下是乱码,而UTF-8在Windows下可以正常识别。但是Visual Studio有可能会出问题!!

VS的编译器对Unicode源代码支持如下:
1. UTF-16 little endian with or without byte order mark (BOM)
2. UTF-16 big endian with or without BOM
3. UTF-8 with BOM

使用Windows下的Visual Studio编译器建议使用ASCII编码,但是如果代码是跨平台的,难免会把Linux平台下的UTF-8编码的文件放到Windows下使用。

这种情况下一般VS会给予如下warning:

warning C4819: 该文件包含不能在当前代码页(936)中表示的字符。请将该文件保存为 Unicode 格式以防止数据丢失

这时候如果出现以中文结尾的一行注释,那么这个换行符很可能会被丢掉,导致下一行代码被注释(并不是一定会出错,估计是和对应字符的编码值有关,这个概率还是很高的。在文本中间插入或删除字符很容易改变这种性质,因此就会出现“改了行注释代码就执行错了”的诡异bug或者“改了下注释代码就执行对了”的诡异“解决方案”)。有时候会出现如下编译错误:

error C2447: “{”: 缺少函数标题(是否是老式的形式表?)

这是因为你的函数名那一行上面的中文注释导致函数名那一行被编译器认为是注释了,如下:

// 中文注释
void func()  // 这一行被当作是注释了
{
    do_something...
}

而这种bug并不是所有情况下都会在编译时被发现,能在编译时发现的bug都是好“bug”。但有些再编译期可能发现不了,比如如下代码就坑多了:

// 中文注释
if(xxx)  // 这一行被当作是注释了
{
    do_something...
}

对于如上的代码,可能就会由于编码的原因导致if(xxx)部分被当作注释,而本来是满足if条件才执行的do_something就变成了一律执行,这种错误很难被发现。

所以跨平台传输代码最好使用git的自动转码功能(Windows平台的git安装的时候的默认选项就是这样的)。

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐