我刚编译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
代替=
?
我可以相信所有这些代码都已生成但无法以无警告的方式生成?
我不是任何方面的专家,我真的很好奇。
答案 0 :(得分:1)
正如汉斯和弗阿德指出的那样,这是当时的规范。在该语言的发明者Brian Kernighan和Dennis Ritchie之后,它被称为K&R C
。 (请注意,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中分发的finger命令)启发了IOCCC –国际混淆C代码竞赛。
可以在rsc's site上找到该代码的实际示例,可以在here上找到(我假设是)完整的源代码。
顺便说一句,如果您认为收到的警告数量很多,则应尝试启用其他警告。尽管我没有最新的清单,但有很多可靠且有用的装置,但默认情况下未启用。 -Wall
-Wextra
将是一个不错的开始。
答案 1 :(得分:0)
实际上,如果您从计算机科学或数学的角度来看它,那是有道理的。 “ C”语法绝对不是主流,以至于我们甚至都没有考虑它。但是那时=
是相等的,并且仍然处于数学上下文中。使用=
作为赋值运算符是一种奇怪且令人困惑的选择。新手程序员有时会将其与数学等式混淆。相反,R使用<-
或->
,Maxima和Modelica使用:=
,它们都是数学家设计的语言。 and
,or
,not
和is
也是不错的选择,例如在Python中使用。从编程的角度来看,以这种方式使用预处理宏是一个可怕的主意,但是如果您考虑其基本原理,则实际上应该归咎于C
。