为什么三字母在现代C++编译器中会产生错误?

Pra*_*nny 8 c c++ gcc compiler-errors

使用Turbo C++编译的三字符程序的屏幕截图

即使在GCC编译器中,如果没有明确指定trigraph属性,也不会编译三字符.

#include<stdio.h>

int main()
 {
 int a=4;
 if((a==4) ??! (a==5))
   printf("\nHello world!");
 return 0;
 }
Run Code Online (Sandbox Code Playgroud)

保存为try.c的程序仅在我们指定时才在GCC编译器中编译gcc -Wall -trigraphs try.c,并且仍然显示警告.你可以招募一些能够处理和处理三字符而没有任何错误或警告的编译器吗?

Kei*_*son 10

Trigraphs由1989 ANSI C标准引入,并保留在所有后来的C标准中.它们也出现在1998年发布的第一个ISO C++标准中,以及C++ 14以后的所有后来的C++标准中.(Trigraphs将在C++中删除17.感谢Jonathan Leffler和dyp追踪细节.)

它们不是任何一种语言的可选功能; 所有符合要求的编制者必须支持它们并按照相应的语言标准对其进行解释.

例如,如果这个程序:

#include <stdio.h>
int main(void) {
    if ('|' == '??!') {
        puts("ok");
    }
    else {
        puts("oops");
    }
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

打印oops,然后你的编译器不符合.

但许多(可能是大多数)C编译器默认情况下并不完全符合.只要编译器能够以某种方式符合标准,就标准而言,这就足够了.(gcc要求-pedantic并且-std=...这样做.)

但即使编译器完全符合,标准中也没有任何内容禁止编译器警告它喜欢的任何东西.符合标准的C编译器必须诊断任何违反语法规则或约束的行为,但它可以发出任意数量的附加警告 - 并且无需区分所需的诊断和其他警告.

Trigraphs很少使用.绝大多数开发系统直接支持所有这三字母替代的人物:#,[,\,],^,{,|,},~.

事实上,很可能是三字母使用不慎往往比他们正确使用:

fprintf(stderr, "What just happened here??!\n");
Run Code Online (Sandbox Code Playgroud)

关于可能改变程序含义的三字母的警告(相对于语言没有三字母时的意义)是ISO标准允许的,并且恕我直言非常合理.大多数编译器可能有选项来关闭此类警告.

相反,对于实现三字符的C++ 17编译器,警告在C++ 14或更早版本中被视为三字符的序列是合理的.同样,禁用此类警告的选项将是一件好事.

  • 请注意,三元组在C++ 14中已被弃用,并将从C++中删除17. (2认同)

Jon*_*ler 5

GCC对三卦过敏.您必须明确启用它们:

gcc -trigraphs ...
Run Code Online (Sandbox Code Playgroud)

GCC 4.7.1手册说:

-trigraphs

支持ISO C三字符.该-ansi选项(和-std严格的ISO C标准的选项)暗示-trigraphs.

它还说:

-Wtrigraphs

如果遇到任何可能改变程序含义的三字符,则发出警告(注释中的三字符不会被警告).此警告已启用-Wall.