为什么GCC在使用三角图时发出警告,而在使用有向图时却不发出警告?

为什么GCC在使用三角图时发出警告,而在使用有向图时却不发出警告?,c,gcc,compiler-warnings,digraphs,trigraphs,C,Gcc,Compiler Warnings,Digraphs,Trigraphs,代码: 但是当我将main的主体更改为: source_file.c: In function ‘main’: source_file.c:8:5: warning: trigraph ??< converted to { [-Wtrigraphs] ??< puts("Hello Folks!"); ??> ^ source_file.c:8:30: warning: trigraph ??> converted to } [-Wtrigraphs]

代码:

但是当我将
main
的主体更改为:

source_file.c: In function ‘main’:
source_file.c:8:5: warning: trigraph ??< converted to { [-Wtrigraphs]
     ??< puts("Hello Folks!"); ??>
 ^
source_file.c:8:30: warning: trigraph ??> converted to } [-Wtrigraphs]

不会抛出任何警告

那么,为什么编译器在使用三角图时警告我,而不是在使用有向图时警告我?

这为警告提供了一个很好的理由(强调我的警告):

三角图并不流行,许多编译器都错误地实现了它们。可移植代码不应依赖于转换或忽略的三角图。使用-Wtrigraphs时,GCC将在一个trigraph如果被转换,可能会改变程序的含义时发出警告

在本gcc文件中,解释了与三角图不同的有向图不会产生潜在的负面影响(重点是我的):

< > >还有六个有向图< /强>,C++标准称为替代令牌,这只是拼写其他标点符号的替代方法。这是第二次尝试解决过时系统中缺少标点符号的问题与trigraphs不同,它没有负面副作用


可能是因为它没有负面的副作用,不同于文献中所述的三角图:

标点符号是标点符号的常用符号,对C和C++都有意义。ASCII中除三个以外的所有标点字符都是C标点符号。例外情况为“@”、“$”和“`”。此外,所有两字符和三字符运算符都是标点符号。还有六个有向图,C++标准称为替代令牌,它们只是拼写其他标点符号的替代方法。这是第二次尝试解决过时系统中缺少标点符号的问题。与三角图不同,它没有负面的副作用,但没有覆盖那么多的区域。有向图及其对应的标准标点是:

有向图:%:%:%:
标点符号:{}[]###

因为三角图具有静默更改代码的不良效果。这意味着相同的源文件在使用和不使用trigraph替换时都是有效的,但会导致不同的代码。这在字符串文本中尤其有问题,例如
“什么?”

语言设计和语言演变应该努力避免无声的变化。让编译器对三角图发出警告是一件好事


与有向图相比,有向图是一种不会导致无声更改的新标记。

有向图令人讨厌,因为它们使用的字符序列可能合法地出现在有效代码中。导致经典Macintosh代码出现编译器错误的常见情况:

 Digraph:        <%  %>  <:  :>  %:  %:%:
 Punctuator:      {   }   [   ]   #    ##
Trigraph处理会将其转化为:

unsigned int signature = '????';  /* Should be value 0x3F3F3F3F */
当然不会编译。在一些稍微少见的情况下,这种处理可能会产生可编译的代码,但与预期的含义不同,例如

unsigned int signature = '??^;  /* Should be value 0x3F3F3F3F */
会变成什么

char *template = "????/1234";
不是预期的字符串文字,但仍然完全合法


相比之下,有向图相对来说是良性的,因为除了一些可能涉及宏的奇怪的角落案例之外,如果没有这样的处理,任何包含可处理有向图的代码都不会有合法的含义。

可能重复@ShafikYaghmour我认为那里的答案包含了这个问题答案中可以给出的所有信息,即使是新版本(或不同的前端?)gcc将其对三角图的处理降级为警告。@ShafikYaghmour链接的问题仍然说gcc生成警告,错误来自Turbo C。因此,我认为此后没有任何变化。@BlueMoon我刚刚意识到行为出现不同的原因是现在几乎每个人都在使用
-std=xxx
,这意味着
gcc
将自动打开trigraphs。因此,也许我同意这是一个复制品。trigraph和digraph是在许多/大多数键盘没有合适的键的时候出现的。今天,所有这些都过时了,不应该被使用。这并不能回答为什么有向图不发出警告(或者暗示它们更受欢迎)@schnaader这是一个暗示,但我添加了另一个文件,明确说明三个答案告诉了同样的事情,但我喜欢你的答案,因为它包含简短、正确的引用。滴答声传给你!:)
unsigned int signature = '??^;  /* Should be value 0x3F3F3F3F */
char *template = "????/1234";
char *template = "??S4"; // ??/ becomes \, and \123 becomes S