三元组由 1989 年的 ANSI C 标准引入,并保留在所有后来的 C 标准中。它们还出现在 1998 年发布的第一个 ISO C++ 标准中,以及后来的所有 C++ 标准中,直到并包括 C++14。(三合符在 C++17 中被删除。感谢 Jonathan Leffler 和 dyp 追踪细节。)
引用 C++17 标准的草案:
对原始特征的影响:使用三元组的有效 C++ 2014 代码在本国际标准中可能无效或可能具有不同的语义。如果三元组出现在原始字符串文字之外,实现可以选择转换 C++ 2014 中指定的三元组,作为实现定义的从物理源文件字符到基本源字符集的映射的一部分。
它们不是任何一种语言的可选功能(C++17 之前);所有符合标准的编译器都必须支持它们并按照各自语言标准的规定解释它们。
例如,如果这个程序:
#include <stdio.h>
int main(void) {
if ('|' == '??!') {
puts("ok");
}
else {
puts("oops");
}
return 0;
}
prints oops
,那么您的编译器不合格。
但是许多,也许是大多数,C 编译器默认情况下并不完全符合。只要可以使编译器以某种方式符合标准,就标准而言,这就足够了。(gcc 需要-pedantic
并-std=...
这样做。)
但即使编译器完全符合标准,标准中也没有任何内容禁止编译器警告它喜欢的任何东西。符合标准的 C 编译器必须诊断出任何违反语法规则或约束的行为,但它可以发出任意数量的附加警告——它不需要区分所需的诊断和其他警告。
三元组很少使用。绝大多数开发系统直接支持三元组替代的所有字符:#
, [
, \
, ]
, ^
, {
, |
, }
, ~
.
事实上,三元组的意外使用可能比正确使用的频率更高:
fprintf(stderr, "What just happened here??!\n");
关于可能改变程序含义的三元组的警告(相对于如果语言没有三元组的含义)是 ISO 标准允许的,恕我直言,这是完全合理的。大多数编译器可能都有关闭此类警告的选项。
相反,对于不实现三元组的 C++17 编译器,警告在 C++14 或更早版本中可能被视为三元组的序列和/或提供支持三元组的选项是合理的。同样,禁用此类警告的选项将是一件好事。