gcc与BOM

在调试进程中遇到coredump,发现源码行号与gdb提示不符。通过排查,确定源文件为gb2312编码,且包含非法字符。在尝试将编码转换为utf-8时,出现编译错误。研究后发现是BOM(Byte Order Mark)导致,因为gcc无法识别带有BOM的utf-8文件。解决方法是将文件转为utf-8无BOM格式,问题得到解决,同时避免了字符数组越界导致的coredump。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

今天遇到一个进程coredump, 在调试时有几个奇怪的现象:
1. 在gdb的时候发现源码和gdb提示的行号对应不起来;
2. 然后用svn查看日志的时候,打开文件提示cannot show diff because of inconsistent newlines in the file.

此时我第一感觉就是源文件里有非法字符,于是用notepad++打开:
发现文件格式是gb2312编码格式,且是以LF结尾的unix换行风格,但是发现有几个CR字符,把他们删掉统一风格;
因为这个文件存在不同编码的汉字注释,我就想顺便把它们也统一一下,以后都用utf-8.于是使用encoding->convert to utf-8转换编码;

再进行编译提示错误如下:

tpn_pu_main.c:1: error: stray '\357' in program
tpn_pu_main.c:1: error: stray '\273' in program
tpn_pu_main.c:1: error: stray '\277' in program

characters can be specified by \nnn where nnn is the octal code for the character.

但是文件里根本就显示不出来这三个字符,于是就想到了BOM标识,搜了下有关BOM的知识:

Byte Order Marks are special characters at the beginning of a Unicode file to indicate whether it is big or little endian, in other words does the high or low order byte come first. These codes also tell whether the encoding is 8, 16 or 32 bit. You can recognise Unicode files by their starting byte order marks, and by the way Unicode-16 files are half zeroes and Unicode-32 files are three-quarters zeros.

BOM可以看作是文件的magic number,常见的有:

EF BB BF UTF-8  #UTF-8不需要BOM来表明字节顺序,但可以用BOM来表明编码方式
FF FE UTF-16 aka UCS-2, little endian
FE FF UTF-16 aka UCS-2, big endian
00 00 FF FE UTF-32 aka UCS-4, little endian.
00 00 FE FF UTF-32 aka UCS-4, big-endian.

于是我又查看了utf-8的BOM对应的八进制序列:
adtsh@adtsh-H110-4S:~$ echo “obase=8;ibase=16; EF; BB; BF” | bc
357
273
277
正好验证了我的猜测,是gcc不能识别BOM导致编译失败
为了再次验证这个猜测,我又编写了一个hello world,保存为utf-8格式,编译时提示同样的错误。

找到原因之后就好办了,把文件的编码改成utf-8 without BOM格式,编译就通过了,源码也能对应起来了,再最后coredump的问题也搞定了,是字符数组越界导致的coredump! 所以一定要使用带n系列的printf函数。

注意:

BOM不受欢迎主要是在UNIX环境下,因为很多UNIX程序不鸟BOM。
vim下去掉BOM标记: set nobomb; set fileencoding=utf8; w

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值