C\C++:编译器偶然的bug-三联符序列

编译器偶然的bug-三联符序列(C\C++)

其实在由三个字母组成的具有转义功能的一组符号

1. 三联符序列

  • 三联符序列其实就是由两个?号外加另外一个符号组成的三个符号的具有转义功能的一组符号。

  • 在ANSI标准,定义了 ??* 表示的一类字符,称为三联符序列。

  • C99 中它英文名为 “trigraph sequence”。

2. 存在的意义

早期有些设备不支持ASCII的字符集(现在你已经看不见不支持ASCII的字符集的设备了),比如某些七位代码集,那些字符集相比ASCII的字符集缺少一些字符, 为了使C程序能在这些非ASCII的字符集电脑上编写, 就必须想办法实现这些字符,用其它字符替代就是一种好办法,三联符序列就是c标准里面制订的一套符号替代的方案的标准。

3. 以前的完美,现在的bug

以前的一种看似比较好的解决方案,现在却成了一种极其偶然的bug,由于现在的各种教程都不讲这些东西,结果知道这些的人非常少,没有人会注意。而不一样的编译器对这个支持的也有不同,所以当跨平台移植的时候,可能会产生不一样的效果。而且三联符序列不管写在程序的哪里都会有效果,包括注释里,字符串里。于是三联符序列导致的bug就诞生了。

举例1:

//注释语句??/
printf("Hello World!\n");

这个printf函数不会输出,因为它被注释掉了。

‘??/’ 将被翻译为’ \ ',在c语言中反斜杠表示断行(编译的时候和下一行先连接一体在编译),所以从最开始的//连着printf一起注释掉了。这将是一个非常大的隐患,这表示有可能您写了一句非常重要的代码,结果不执行,而且编译不报警告也不报错。恐怖不!如果出现在一个大项目里,这将要使人崩溃。

举例2:

??=include "stdio.h"
int main()??<
	return 0;
}

这个会被编译成功,因为’??=’ 将被翻译为’ # ‘, ‘??<’ 将被翻译为’ { ', 您感觉这是不可思议,但是 vc2008 编译成功了。而且这是正确的语法。

举例3:

//来自《Pointers On C》
printf("Delete flie (are you really sure??)")

这是我们经常会出现的错误:’??)’ 将被翻译为’ ] '. 上面这条语句输出变成:

Delete flie (are you really sure]

乱码了?,不,其实这是正确的输出。

4. 常出现的几个三联符序列

三联符列表被编译器当作的字符
??=#
??([
??)]
??<{
??>}
??/\
??!|
??’^
??-~

5. 并不是所有编译器都支持三联符序列

三联符序列支持与否,和编译器有关,不一样编译器对ANSI C 的支持情况也不一样(如GCC:我们称它采用了扩展的c标准,即增加了很多c标准里面没有的东西,同时也删了一些它认为c标准里面没有用的东西),编译器效果也不同,所以有些编译器可能会不处理三联符序列,将他视为字符串。

由于本人是做嵌入式开发,因此测试更加偏重嵌入式方向,下面是常见编译器下举例,其他环境当我用到会再次补充。

5.1 win + vscode + MinGW环境:

默认不支持三联符序列,使用三联符序列会当成字符串,同时会给出警告

当在程序里面写有 ??/

//注释语句 ??/
c = a+b;

编译报警告如下:

trigraph ??/ ignored, use -trigraphs to enable [-Wtrigraphs] gcc

5.2 win + keil5 + c99环境:

支持,并且edit的变色,反而让您更难发现问题。有的时候出现三联符序列时编辑器会在前面显示一个红叉,但是编译不会报错也没有警告。

在这里插入图片描述

5.3 vc环境:

vs2008是支持的,我让我同事测试的(因为我电脑硬盘有限,VS studio太大了),他没给我截图,但是他测试了我的代码,告诉我说vs2008是支持的。

5.4 linux + GNU的gcc环境:

还未来得及实验

5.5 css10 + TI clang环境(TI推荐的开发环境之一):

不支持三联符序列。
在这里插入图片描述

5.6 像阿里平头哥、沁恒mcu这种用于编译RISC-V内核的程序的编译器

不支持三联符序列,但这只是实验了两家产品,并不保证所有用于编译RISC-V内核的程序的编译器都如此。

6. 总结:莫要轻易打 ?? 号

由于不一样的编译器对三联符序列支持的不同,当代码需要跨平台,可能在您的电脑编译后运行正常,在他电脑环境下编译运行就会疯狂,所以最好的做法就是我们千万不要连续打出两个ASCII码 ? 号, 这样可以有效避免三联符序列导致的问题。

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

哈搭石

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值