-2

GCC 将int i=048;其视为错误,因为048应该是八进制数,但8不能出现在八进制数中。

但是为什么 GCC 不能更智能,把 is 当作十进制数呢?

4

4 回答 4

7

因为如果将 048 解释为十进制,它将违反语言“C”的句法规则。任何以 0 开头的数字都应解释为“八进制”。

这是一件好事,因为编译器努力做到符合标准。

还假设您正在为自己的 C 编译器编写 C 解析器,它实际上可以“理解”您的意思048, 049..是所有十进制数。现在你将如何制作那个解析器?它可能但令人难以置信的复杂。以及大量错误的来源。

于 2012-11-05T02:05:24.473 回答
6

这并不是 GCC 的错,因为它努力符合标准。

但是想象一下,如果它确实排除了“如果数字标记以 0 开头但不是八进制,则将其视为十进制”的形式。这条规则不仅相对复杂——“如果代码以通常的方式没有意义,则回退到另一种解释,看看它是否有意义”——而且它还呈现出各种其他意想不到的行为:

/* My bearings */
int east      = 000;  // 0 in Octal = 0
int northeast = 045;  // 45 in Octal = 37
int north     = 090;  // Starts with 0 but contains 9, must be decimal = 90
int northwset = 135;  // Starts with 1, is decimal = 135
...

确实,具有现有行为的类似代码也可以通过编译器并带有变量的意外值。关键是添加一个特殊规则来帮助您的案例将留下其他案例。最好是捕获错误并将其视为错误,而不是找出其中一些可以不同的解释。

(FWIW,我从来没有使用过八进制表示法,并且发现它的存在很可怕,因为在许多其他情况下,我会用 0 填充十进制数字来表示。记住永远不要在 C 中这样做需要一点额外的脑力。)

于 2012-11-05T02:13:18.083 回答
5

C 语言要求在这种情况下发出诊断(错误)。GCC 必须遵守。

除此之外,您提倡的行为类型是极其有害的。它会掩盖各种错误/错别字,并引入非常混乱的不一致。例如,如果某些代码包含:

int x = 01800;

而您将 更改1820, 的值x实际上会减少!

于 2012-11-05T02:06:49.633 回答
5

如果您输入,您会期望更高的智能gcc必须做什么

int i=047;

...然后,随后,如果您的一位同事将程序更改为阅读,您会期待什么

int i=049;

..您和他或她会因为仅添加“2”而得知值已从 更改为3949

最小惊讶原则有助于指导各种设计人员,毫无疑问,这可能是 C 语言设计中的一个因素。


也就是说,更不令人惊讶的是八进制文字,它不仅仅是一个前导零。为此,像 python 和 rust 这样的语言将八进制编码为“ 0o47”(类似于 C 等人的十六进制文字)。

于 2012-11-05T02:12:45.657 回答