微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

这个解释对于无法编译的C代码是否准确?

涉嫌面试问答 here.

以下代码是否会编译(在C中)?

#define X 8;
int main(void)
{
    ++X; // will this line compile?
}`

我不是C的专家,但我知道一些C和思想:当然不是,你不能增加数字8,它是一个右值.当然,预处理器在尝试编译之前将X替换为8,当它尝试编译时,它会因为这个原因而失败.然后,我是一个阅读面试问题的网站,所以我想谁知道…

这是给出的解释:

“严格来说,前缀(或后缀)增量运算符的操作数必须是一个不可修改的左值.现在我们知道左值是什么,我们必须问自己X是否是左值.X是一个宏,这意味着它不能识别内存中的位置 – 宏通过预处理器使用简单的文本替换.因为宏不存在于内存区域,所以它们不是左值.这意味着X不能用作前缀增量的操作数因此,上面显示代码将无法编译.“

这个解释是否像我认为的那样是无聊的?

你上面能找到多少错误?我想也许这应该是面试问题……

这很有趣:

“直观地说,你可能会说上面的代码无法编译 – 如果不确切知道原因.但是,在面试的情况下,你会被期望提供一些像上面给出的那样的推理.简单的是或否答案刚赢了”在接受采访时削减它.“ (!)

解决方法

Is this explanation as bunk as I think it is?

是.

“Strictly speaking,the operand of the prefix (or postfix) increment operator must be a non-modifiable lvalue…

什么?不可修改的左值类似于const int n; – 您可以获取其地址(通过&)但不能分配给它(via =,=或).你不能增加一些不可修改的东西.

引用标准(6.5.3.1第1段):

The operand of the prefix increment or decrement operator shall have qualified or
unqualified real or pointer type and shall be a modifiable lvalue.

咳咳.

X is a macro,which means that it does not identify a place in memory – macros use simple text replacement via the preprocessor.

这是假的. C语言中不存在宏*.它们是预处理器的一部分,它没有左值,右值,表达式或内存的概念.这个特定的宏扩展为一个整数常量,它是一个rvalue,但宏本身与上面的任何一个都没有关系.有关作为左值的宏的反例,请参见Steve Jessop’s answer.

正确的答案是语句扩展为8,因为8是一个rvalue,它不能用作(以任何一种形式)的参数,因此它不会编译.此外,根据您是否打算将此代码编译为C89或C99,保留main而没有显式返回值可能会给出未定义的行为.

*如果这将成为公认的答案,我想我应该澄清这一点:预处理器是C编程语言的一部分.它在C标准中指定,并且编译器必须实现预处理才能成为C编译器.但是,C语言(即语法,语义,库等)不与预处理器交互 – 一旦你进入开始处理左值和右值的阶段,预处理器早就完成了所有宏都完全展开.宏本身在语法中没有任何位置,因为它们不是“语言”的一部分.关于在这里使用“语言”这个词是否具有误导性的问题存在争议(在Steve Jessop的回答中),我同意他的看法,我找不到更好的词来代替.

原文地址:https://www.jb51.cc/c/116626.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐