【问题标题】:Strange "+=" behaviour奇怪的“+=”行为
【发布时间】:2010-10-13 14:20:11
【问题描述】:

这个代码段必须返回什么? 16 16 16 对吗?

int main(int argc,char *argv[])
{
   int a=2,*f1,*f2;
   f1=f2=&a;
   *f2+=*f1+=a+=2.5;
   printf("%d %d %d\n",a,*f1,*f2);
   return 0;
}

奇怪的是,它返回 8 8 8 给我 ???? :-(

【问题讨论】:

  • 谁让你写代码的?!?
  • 提问者可能不知道,但这是stackoverflow.com/questions/949433/…的另一个微妙变体
  • 那个怪物是什么?你的老师喜欢在背后捅刀子吗?这种行为甚至没有被定义/保证 xD
  • 是的,避免无关紧要的“知识”是一门艺术:)
  • Yashwant Kanitkar 测试你的 C 技能?

标签: c


【解决方案1】:

要真正了解这里的问题,请尝试sequence points 上的comp.lang.c FAQ 文章。

【讨论】:

  • 哦!我从来没有想过,尽管我从来没有遇到过问题,但知道事情是未定义(或未指定)的行为总是很好的。特别是,因为在实践中,我已经意识到存在某种序列点,但不知道它们被记录在案。很好的解释!
【解决方案2】:

*f2+=*f1+=a+=2.5;

相同的旧未定义行为。

【讨论】:

  • @Prasoon:如果,正如我开始怀疑的那样,你编写了一个机器人来扫描新问题的实例,并迅速提醒你有机会快速获得大量点,那么您应该完全将其提交给 GCC 以用于发出有关狡猾代码的警告;-)
  • @Steve : CW [现在没有更多代表]。
  • @Steve:不,可能他只是在向所有这些人教 C,而且在课程开始时,当他告诉他们 SO 是获得所有答案,然后当他教他们 UB 时,他们中的一部分慢慢地睡着了。
  • @Steve :现在我决定不发布这类问题的答案。
  • @Prasoon:对不起,我无意批评它。我认为你回答得很好:人们需要在花很多时间对 UB 实际上是什么非常错误之前被告知这种事情,就像你上次处理的那样。所以你应该得到你这样做的支持。我只是想开玩笑说你这么快就到了最后一对。我想起了一位老同事,他有一个程序扫描他的电子邮件中的单词“饼干”(美国:“cookie”)并在屏幕上弹出一个警报。
【解决方案3】:

这是未定义的行为,因为a 的值在该分配字符串中被多次修改。所以你所期望的都是没有意义的。

【讨论】:

    【解决方案4】:

    根据规范 6.5/2,这是未定义的行为,因为您在序列点之间多次修改对象:

    在上一个和下一个之间 序列点对象应 将其存储值修改为 最一次通过评估 表达。此外,之前的 值应只读以确定 要存储的值。

    【讨论】:

    • 而且由于行为未定义,任何结果都是可能的,无论它看起来是否有意义。
    【解决方案5】:

    好像翻译成

    *f2 += 2;
    *f1 += 2;
      a += 2.5;
    

    而且+= 不像= 那样具有传递性。

    【讨论】:

    • 它本质上与“a += a += a += 2.5”相同,并且非常适合鼻恶魔领域。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-06-08
    • 2015-07-20
    • 2010-10-03
    • 2021-07-12
    • 2013-10-04
    • 2019-01-23
    • 2012-07-13
    相关资源
    最近更新 更多