【问题标题】:Why NIST RS274NGC G-Code Interpreter uses this code style?为什么 NIST RS274NGC G-Code Interpreter 使用这种代码风格?
【发布时间】:2018-02-21 11:25:35
【问题描述】:

我刚刚编译了NIST RS274NGC G-Code Interpreter ,看到来自 gcc 的令人难以置信的 890 个警告。

其中200个是由这个数组引起的:

char * _rs274ngc_errors[] = {
/*   0 */ "No error",
/*   1 */ "No error",
/*   2 */ "No error",
/*   3 */ "No error",
/*   4 */ "A file is already open", // rs274ngc_open
<...>

根据我的基本理解,应该是const char *

然后我看到了这些宏(它们实际上在不同的 .cc 文件中出现了好几次):

#define AND              &&
#define IS               ==
#define ISNT             !=
#define MAX(x, y)        ((x) > (y) ? (x) : (y))
#define NOT              !
#define OR               ||
#define SET_TO           =

然后我看到很多警告suggest braces around empty body in an 'else' statement [-Wempty-body] 是由像这样的非常奇怪的控制流更改宏引起的(是的,还有悬空!):

#define PRINT0(control) if (1)                        \
          {fprintf(_outfile, "%5d \n", _line_number++); \
           print_nc_line_number();                    \
           fprintf(_outfile, control);                \
          } else

报告表明

A.5 解释器错误

解释器没有已知的错误

所有这一切都让我想知道 - 为什么它写得如此奇怪?我可以理解 PRINT0 之类的宏 - C 中的错误处理可能会很痛苦 - 但为什么有人会使用 SET_TO 而不是 =

我可以相信所有这些代码都是生成的,但它不能以无警告的方式生成吗?

我不是专家,我只是很好奇。

【问题讨论】:

  • 这只是一段非常古老的代码,RS-274 可以追溯到 1980 年。作者还没​​有使用那么挑剔的 C 编译器。那时没有。我认识到编程风格,作者有 Algol 或 Pascal 的背景。还没有完全消失,今天字符串文字的类型仍然是 char*,宏仍然部分被 iso646.h 覆盖。 Pascal 没有悬空的 else 问题,if-then-else 是一条以分号结尾的语句。
  • 我不知道您启用了哪些设置,但文字字符串的类型为 char *
  • @AnttiHaapala 我想我用 g++ 编译了那个位,所以它实际上是一个 C++ 警告。
  • @HansPassant 您能否将您的评论作为答案,以便我接受?
  • @HansPassant 有趣的是,我提到的报告日期为 2000 年。

标签: c macros warnings g-code


【解决方案1】:

正如 Hans 和 Foad 所指出的,这是当时的常态。它被称为K&amp;R C,以该语言的发明者 Brian Kernighan 和 Dennis Ritchie 的名字命名。 (请注意,K&R C 也可以参考他们在撰写第一本关于该语言的书时普及的格式样式。)

K&R C 非常容忍 C99 或 C11 模式下的编译器会将其视为 UB(未定义行为)或完全语法错误,例如定义带 args 的函数而不指定 args 的类型。当时,假设这样的函数采用 int args。

IIRC 对该语言的第一次重大改革是 ANSI C '89;计算机能力、编译器和语言的流行度在其发明和标准化之间发生了巨大变化。

如果您对过时的 C 感兴趣,您可能希望查看 Bourne shell 的源代码。引用维基百科的Bourne Shell 文章:

Stephen Bourne 的编码风格受到他使用 ALGOL 68C 编译器经验的影响...

... Bourne 利用一些宏使 C 源代码具有 ALGOL 68 风格。这些宏(以及在 Unix 4.2BSD 中分发的手指命令)激发了 IOCCC – 国际混淆 C 代码竞赛。

代码的实际示例可以在rsc's site 上找到,并且(我假设是)完整的源代码可以在here 上找到。


顺便说一句,如果您认为收到的警告数量很多,您应该尝试打开其他警告。有很多可靠且有用的,但默认情况下不启用,尽管我没有它们的最新列表。 -Wall -Wextra 将是一个不错的开始。

【讨论】:

  • 我只是没想到会在 '8 月17, 2000' :) 我通常启用-Wall -Wextra -Wpedantic
  • 啊,是的。我已经看到 NIST 的一些其他代码也使用了过时的技术。保持最新的最佳实践似乎并不是一个优先事项。
【解决方案2】:

实际上,如果您从当时的计算机科学或数学角度来看,这是有道理的。 “C”语法现在如此主流以至于我们甚至都没有考虑它。但当时= 是相等的,它仍然是在数学上下文中。使用= 作为赋值运算符是一个奇怪且相当混乱的选择。新手程序员有时会将其与数学等式混淆。相比之下,R使用&lt;--&gt;,Maxima和Modelica使用:=,都是数学家设计的语言。 andornotis 也是不错的选择,例如在 Python 中使用。从编程的角度来看,以这种方式使用预处理宏是一个可怕的想法,但如果你考虑一下基本原理,实际上应该归咎于 C

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-06
    相关资源
    最近更新 更多