语言c,编译时错误多次无序修改[-Werror,-Wunsequenced]

时间:2015-12-14 12:12:37

标签: c

这是我职能的定义:

char *strsub(char const *s, unsigned int start, size_t len){
   blabla
   blabla
   while (len > 0)
   {
      len--;
      cpy[start++] = s[start++];
   }
}

当我尝试编译时,我收到此错误:

  

错误:多个未经过排序的修改启动-Werror,-Wunsequenced

我根本不明白这个错误。

3 个答案:

答案 0 :(得分:4)

cpy[start++] = s[start++];

在此,您可以多次修改start,而无需插入序列点。这是未定义的行为。你的编译器帮助指出了这一点。

如果您想将字节从一个位置复制到另一个位置,您可能无论如何都不想修改start两次。所以,做:

while (len > 0)
{
   len--
   cpy[start] = s[start];
   start++;
}

请阅读:

Undefined behaviour and sequence points

A Guide to Undefined Behavior in C and C++

What Every C Programmer Should Know About Undefined Behavior

了解有关此主题的更多信息。

答案 1 :(得分:2)

这是

cpy[start++] = s[start++];

应该增加start一次或两次?虽然您可能知道答案,但编译器却摸不着头脑。

可能存在具有定义结果的语言(通常按从左到右的评估顺序),但C不是其中之一(它是未定义的行为)。

错误消息中的 unsequenced 一词指的是序列点的C语言概念。在所示的表达式中,只有一个序列点 - 分号。但有两个后增量。哪一个应该先执行? C将此打开^ Wundefined。

答案 2 :(得分:0)

直接从C11引用,章节§6.5.16,分配运算符

  

[...]更新左操作数的存储值的副作用是   在左右操作数的值计算之后对进行排序。评估   操作数没有排序。

这意味着,在您的代码中,

cpy[start++] = s[start++];

你试图多次修改start的值而没有一个序列点,这是完全错误的,并会调用undefined behavior