考虑到以前在C和C++中使用双字母组合和三字母组合的原因,现在是否有人将它们放入正在编写的代码中?是否还有大量需要维护的遗留代码包含它们?
(注意:这里,“digraph”不是指“有向图”。Digraph和trigraph都有多重含义,但此处意图使用的是像??=
或<:
这样的序列,以代替像#
和[
这样的字符。)
puts("What happened??!");
参考资料:三字符序列(trigraphs)是在1989年的ANSI C标准中引入的(本质上成为了1990年ISO C标准)。它们包括:
??= # ??) ] ??! |
??( [ ??' ^ ??> }
??/ \ ??< { ??- ~
<: [ :> ]
<% { %> }
%: # %:%: ##
二元组是由1995年对1990年ISO C标准的修订引入的。
puts("What happened?" "?!\n");
以获得正确的输出。 - Gzorgputs("What happened?\?!\n");
- Rhubbarb(*
和*)
用于打开和关闭花括号。 - dodgethesteamroller有一个C++1z的提案(在C++1y之后的下一个标准,希望能够成为C++14)旨在从标准中删除三字符序列。他们对一份未公开的大型代码库进行了案例研究:
案例研究
我们检查了一个大型代码库中类似三字符序列的结构使用情况。我们发现:
923个实例在字符串文字中转义?以避免三字符替换:string pattern() const { return "foo-????\?-of-?????"; }
4个实例在测试代码中故意使用三字符序列:两个在编译器的测试套件中,另外两个在boost的预处理器库的测试套件中。
0个实例在生产代码中故意使用三字符序列。三字符序列继续给C++用户带来负担。
该提案指出(原始提案中加粗强调):
如果从语言中完全删除三字符序列,则希望支持它们的实现仍可以这样做:其从物理源文件字符到基本源字符集的实现定义映射可以包括三字符序列转换(甚至可以在原始字符串字面值中避免这样做)。 为了向后兼容,我们不需要在标准中使用三字符序列。\?
仍然表示字面上的 ?
字符,因为它是定义的转义序列之一,无论三字符序列是否存在。 - mtraceurand
、or
、not
、bitand
、not_eq
,它们看起来非常明确,因此可以强制执行代码意图。 - daparic它们可以用于国际混淆C代码大赛。
再次强调,我真的希望人们在可能的情况下避免使用它们,但这是了解和使用它们的一个原因。
??(
的实例。请享受这个过程! - Ray Toal??(x)
是一个函数调用的伪代码。通过查找??<
来缩小搜索范围,这代表{
符号,在任何 C 源代码中都是必不可少的。在所有 14 页的搜索结果中,没有一个真正的三字符组例子。它们主要是 HTML 的伪代码,还有一些编译器/编译器测试和 base64 编码的文本。 (我感兴趣是因为我正在编写一个 C++11 预处理器来实践。) - Potatoswatter