代码之家  ›  专栏  ›  技术社区  ›  Christoffer

分配顺序评估(我是否发现了第一个编译器错误?)

  •  2
  • Christoffer  · 技术社区  · 15 年前

    此代码有一个有趣的错误:

    some_struct struct_array1[10] = {0};
    some_struct struct_array2[10] = {0}
    int i;
    
    for (i = 0; 
         i < sizeof(struct_array1) / sizeof(struct_array1[0]); 
         struct_array1[i].value = struct_array2[i++].value = 1)
        ;
    

    对于大多数编译器,上述代码会将各自数组中所有结构的“value”字段设置为1。 但是,对于一个特定的编译器(我们称之为XCC),结构数组1中的结构没有正确初始化。对于所有结构,“value”字段都设置为0,这让我有点惊讶。

    以下代码段在所有编译器上都按预期工作:

    for (i = 0; 
         i < sizeof(struct_array1) / sizeof(struct_array1[0]); 
         i++)
    {
        struct_array1[i].value = struct_array2[i].value = 1;
    }
    

    现在,我是完全离开这里了,还是有问题的编译器“xcc”只是显示一个bug?

    在第一个代码段中,我找不到任何显示特定于实现的行为的内容;根据我的理解,后缀增量应该优先于赋值,赋值应该从右向左计算。第一个代码片段不应该有任何内容,只是有点不可读。

    3 回复  |  直到 15 年前
        1
  •  8
  •   caf    15 年前

    您调用了未定义的行为,因为它修改了 i 并且在没有中间序列点的情况下,为了计算新值以外的目的而获取其值。

    C99标准的相关部分是第6.5节中的本条:

    在上一个序列和下一个序列之间 点一个物体应该有它的存储 值最多修改一次 表达式的计算。 此外,优先值应为 只读以确定 存储。

        2
  •  5
  •   Alexander Gessler    15 年前

    struct_array1[i].value = struct_array2[i++].value = 1

    我认为这是未定义的行为,因为 i++ 在到达下一个序列点之前,不能保证完成所有的副作用。下一个序列点是“假想的” ; 在陈述的结尾。这是一个常见的陷阱,我认为你可以找到很多与之相关的主题,只需搜索序列点。

        3
  •  0
  •   Pavunkumar    15 年前

    实际上,我们不应该对同一个变量执行多个评估,用signle表示

    表达式。如果我们做那件事,那将是未定义的行为。