【问题标题】:Are digraphs and trigraphs in use today? [closed]今天使用二合字母和三合字母吗? [关闭]
【发布时间】:2011-09-16 23:42:08
【问题描述】:

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

(注意:这里,“有向图”不是表示“有向图”。digraphtrigraph 都有多种含义,但这里的预期用途是像 ??=<: 代表#[ 等字符)

【问题讨论】:

  • 我从来没有见过一个(故意的!),但我在游戏中工作,而遗留代码往往要少得多。
  • 享受 Google 代码搜索的乐趣!例如:google.com/codesearch#search/… 将查找 ??( 的实例
  • 别忘了引号! @Ray - 谢谢。我现在要花一个小时查找脏话,并嘲笑随之而来的糟糕代码。
  • @Ray - 谢谢,很有趣!显然,绝大多数出现在字符串文字和 cmets 中,其中 ??(x) 是函数调用的伪代码。搜索范围缩小为 looking for ??<,而 { 在任何 C 源代码中都是必不可少的。 — 在所有 14 页的结果中,没有一个真正的三元图示例。它们大多是 HTML 伪代码,其中包含一些编译器/编译器测试和 base64 编码文本。(我很感兴趣,因为我正在为 C++11 实践编写预处理器。)
  • @Matthieu:但是如果您使用这样的选项,您的代码就会依赖它,并且在没有该选项的情况下编译时要么无法编译,要么具有不同的含义。我宁愿有一个警告,这样我就可以完全避免使用三元组。

标签: c++ c digraphs trigraphs


【解决方案1】:

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

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

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

puts("What happened??!");

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

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

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

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

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

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

【讨论】:

  • 那些 7 位 ASCII-ish 字符集在 1972 年被标准化为 ISO-646,它们在 1980 年代已经不再使用,被 8 位 ISO-8859 变体取代(包括 Windows-1252)到 1990 年代。后者包括所有 7 位 ASCII 字符,并且不需要 C 代码中的三元组。如果仍然存在遗留的 ISO-646 系统,那么它们已经过时了,以至于没有人会为它们编写新的 C 代码。
  • 在这种情况下,写puts("What happened?" "?!\n"); 以获得正确的输出。
  • @Gzorg 三元组也可以通过转义第二个“?”来规避。因此:puts("What happened?\?!\n");
  • 实际上,trigraphs(在 EBCDIC 之后)的次要原因之一是 1970 年代和 80 年代的许多小型计算机都配备了终端键盘,这与今天的 PC / Apple 键盘的标准化非常不同。每个供应商都有自己的键盘布局,有时会在不同的行中有所不同。在某些终端上,输入一些符号并不容易,或者可能直接输入一些符号,例如波浪号、'~',甚至是“(commercial) at”符号“@”,因此需要。我认为 C 甚至没有在其他 IBM 的非 ASCII 系统中实现。
  • @mctylr 许多 70 年代末和 90 年代初的微型计算机也没有遵循 IBM Selectric 或 PC 标准,并且没有所有必需的字符来避免使用 n i>-图。例如,Atari 在他们的 8 位机器上使用的 ASCII 变体 ATASCII 不包括大括号或竖线。为了增加乐趣,我在那台机器上使用了一个 C 编译器,该编译器使用非标准二合符——(**) 用于打开和关闭花括号。
【解决方案2】:

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

案例研究

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

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

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

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

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

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

【讨论】:

  • 但是所有转义的三元组会发生什么??!
  • @Praxeolitic 我知道你在那里做了什么。要知道四年后你的笑话会受到赞赏。至于实际问题,\? 继续表示文字 ? 字符,因为它是定义的转义序列之一,无论是否存在三元组。
  • 我确实同意应该删除一些看起来很奇怪的三字/二字,但也有有用的三字/二字,例如andornotbitand、@ 987654328@ 看起来非常明确,因此强制执行代码意图。
【解决方案3】:

【讨论】:

  • 虽然此链接可能会回答问题,但最好在此处包含答案的基本部分并提供链接以供参考。如果链接页面发生更改,仅链接的答案可能会失效。
  • @ChrisH:IMO 链接不是答案(即,这不是仅链接的答案)。该链接只是为了方便而添加的。
  • @undur_gongor 够公平的。但我想,鉴于它是对一个已有近 3 年历史的问题的回答,该问题已被 17 票以上的答案接受,它相当学术。
【解决方案4】:

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

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

【讨论】:

  • EBCDIC 仍在旧的 IBM 大型机上使用,并且不包括编写 C/C++ 所需的所有字符:(
  • 为什么会是 linker 选项?三元组由编译器处理;链接器甚至不需要知道它们。
【解决方案5】:

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-01-21
    • 2021-09-16
    • 2012-04-26
    • 1970-01-01
    • 1970-01-01
    • 2014-07-31
    • 1970-01-01
    相关资源
    最近更新 更多