41

鉴于曾经有理由在 C 和 C++ 中使用二合字母和三合字母,现在有没有人将它们放入正在编写的代码中?是否有大量包含它们的遗留代码仍在维护中?

(注意:这里的“有向图”并不意味着“有向图”。有向图三联图都有多重含义,但这里的预期用途是序列,如??=或代表和等<:字符)#[

4

5 回答 5

26

我不确定,但您最有可能发现在 IBM 大型机环境中使用的二合字母和三合字母。EBCDIC字符集不包含 C 所需的某些字符。

Digraphs 和 trigraphs 的另一个理由,即用重音字母替换一些标点符号的 7 位 ASCII-ish 字符集,在今天可能不太相关。

在这样的环境之外,我怀疑三元组更常被错误使用而不是故意使用,例如:

puts("What happened??!");

作为参考,在 1989 年的 ANSI C 标准(本质上成为 1990 年的 ISO C 标准)中引入了三元组。他们是:

??= #     ??) ]     ??! |
??( [     ??' ^     ??> }
??/ \     ??< {     ??- ~

替换发生在源代码中的任何地方,包括注释和字符串文字。

Digraphs 是某些标记的替代拼写,不影响注释或文字:

<: [      :>   ]
<% {      %>   }
%: #      %:%: ##

有向图是由 1990 年 ISO C 标准的 1995 年修正案引入的。

于 2011-09-16T23:58:02.463 回答
17

有一个针对 C++1z 的提案(C++1y 之后的下一个标准将被标准化为-希望是-C++14)旨在从标准中删除三元组。他们对一个未公开的大型代码库进行了案例研究:

案例分析

检查了在一个大型代码库中使用类似三元组的结构。我们发现:

923 次逃跑?在字符串文字中避免三元组替换: string pattern() const { return "foo-????\?-of-?????"; }

在测试代​​码中故意使用了 4 个三元组实例:两个在用于编译器的测试套件中,另外两个在用于 boost 的预处理器库的测试套件中。

在生产代码中故意使用三元组的 0 个实例。Trigraphs 继续给 C++ 用户带来负担。

提案说明(原提案中的粗体强调):

如果从语言中完全删除三元组,希望支持它们的实现可以继续这样做:它的实现定义的从物理源文件字符到基本源字符集的映射可以包括三元组翻译(甚至可以避免在原始字符串文字)。为了向后兼容,我们不需要标准中的三元组

于 2014-07-16T13:02:27.487 回答
9

它们可用于国际混淆 C 代码竞赛

于 2014-06-24T15:43:27.050 回答
5

今天还没有使用三和二图,它只存在于在非常有限的环境中创建的非常古老的代码中。任何包含三元组的代码,如果您尝试在像 VS 这样的现代编译器上编译它们,除非您指定链接器选项,否则它通常不会编译。我知道对于 Visual Studio,该选项是“/Zc:trigraphs”

它们之所以存在,是因为 C++ 委员会从不发布会“破坏”遗留代码的更改。不论结果好坏。有一个轶事是他们的移除被提议和支持,它被一个单独的 IBM 代表阻止。

于 2011-09-17T00:29:07.963 回答
3

我知道这是一个老问题,但现在可以说是一个合法的用途:没有实际键盘的触摸屏。例如,如果您通过平板电脑或类似的方式进行任何编码,典型的美国键盘布局不一定以完整形式提供,诚然,由于它的繁琐程度,这种情况希望很少见(为赋值运算符单击我的三下) . 如果可能,我个人不会使用它们,但它们在没有它们要代表的实际标记的情况下很有用。

同样,我真的希望人们尽可能避免这种情况,但这是了解和使用它们的原因之一。

于 2013-02-16T00:55:33.427 回答