首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ >

GCC4.2.4编译时提示 warning: operation on 'b' may be undefined,该怎么处理

2012-02-12 
GCC4.2.4编译时提示 warning: operation on b may be undefinedC/C++ code#include stdio.hint main()

GCC4.2.4编译时提示 warning: operation on 'b' may be undefined

C/C++ code
#include <stdio.h>int main(){    int  a,b,c,d;    a=7,b=7;    a=(a++);    b=(++b);    printf("a=%d,b=%d\n",a,b);    c=a++;    d=++b;    printf("a=%d,b=%d,c=%d,d=%d\n",a,b,c,d);    return 0;}


cc -Wall test.c -0 test  
提示如下:
test.c: In function 'main':
test.c:6: warning: operation on 'a' may be undefined
test.c:7: warning: operation on 'b' may be undefined
虽然没有报错,但是有个warning,还是不舒服。但是自己看了看,没找到如何修正这个warning。
但是这个在VC6.0环境下是可以通过的。
请教在gcc下如何修正warning呢?
谢谢:)

[解决办法]
a=7,b=7;
-------->
a=7;b=7;

应该改成这样吧?
[解决办法]
a=(a++);等价于a++;
b=(++b);等价于++b;
不过我编译时就没有warning,建议升级一下编译器版本
[解决办法]
序列点问题,参考C FAQ,原文件http://c-faq-chn.sourceforge.net/ccfaq/ccfaq.html


4.3 对于代码 int i = 3; i = i++; 不同编译器给出不同的结果, 有的为 3, 有的为 4, 哪个是正确的?

没有正确答案;这个表达式无定义。参见问题 3.1, 3.7 和 11.32。 同时注意, i++ 和 ++i 都不同于 i+1。 如果你要使 i 自增 1, 使用 i=i+1, i+=1, i++ 或 ++i, 而不是任何组合, 参见问题 3.10。


4.1 为什么这样的代码: a[i] = i++; 不能工作?

子表达式 i++ 有一个副作用 --- 它会改变 i 的值 --- 由于 i 在同一表达式的其它地方被引用, 这会导致无定义的结果, 无从判断该引用(左边的 a[i] 中)是旧值还是新值。(注意, 尽管 在 K&R 中建议这类表达式的行为不确定, 但 C 标准却强烈声明它是无 定义的, 参见问题 11.32。
参考资料: [K&R1, Sec. 2.12]; [K&R2, Sec. 2.12]; [ISO, Sec. 6.3]; [H&S, Sec. 7.12 pp. 227-9]。

4.7 我怎样才能理解复杂表达式?``序列点" 是什么?

序列点是一个时间点(在整个表达式全部计算完毕之后或在 ||、 &&、 ? : 或逗号 运算符处, 或在函数调用之前), 此刻尘埃落定, 所有的副作用都已确保结束。 ANSI/ISO C 标准这样描述:
在上一个和下一个序列点之间, 一个对象所保存的值至多只能被表达式的 计算修改一次。而且前一个值只能用于决定将要保存的值。
第二句话比较费解。它说在一个表达式中如果某个对象需要写入, 则在同一表达式中对该对象的访问应该只局限于直接用于计算将要 写入的值。这条规则有效地限制了只有能确保在修改之前才访问 变量的表达式为合法。例如 i = i+1 合法, 而 a[i] = i++ 则非法 (参见问题 3.1)。

参见下边的问题 3.8。

参考资料: [ISO, Sec. 5.1.2.3, Sec. 6.3, Sec. 6.6, Annex C]; [Rationale, Sec. 2.1.2.3]; [H&S, Sec. 7.12.1 pp. 228-9]。

[解决办法]
探讨

引用:

a=7,b=7;
-------->
a=7;b=7;

应该改成这样吧?

这样更改无效。你可以在unix-center注册账号试试。我是在本机用虚拟机做的

[解决办法]
罪魁就是
a=(a++);
b=(++b);这两句
[解决办法]
test.c:6:6: 警告:‘a’上的运算结果可能是未定义的 [-Wsequence-point]
test.c:7:6: 警告:‘b’上的运算结果可能是未定义的 [-Wsequence-point]

[解决办法]
++操作符在C/C++标准中都是存在的。
a=(a++);
b=(++b);
这两个表达式是未定义的,相比较VC6,GCC更加严谨,所以会有这样的警告。

还是参考C FAQ

12.35 有人说 i = i++ 的行为是未定义的, 但是我刚在一个兼容 ANSI 的编译器上测试, 得到了我希望的结果。

面对未定义行为的时候, 包括范围内的实现定义行为和未确定行为, 编译器 可以做任何实现, 其中也包括你所有期望的结果。但是依靠这个实现却不明智。 参加问题 7.4, 11.31, 11.32 和 11.34。

12.32 人们好像有些在意实现定义 (implementation-defin-ed)、未明确 (unspecified) 和无定义 (undefined) 行为的区别。它们的区别到底在哪里?

简单地说: 实现定义意味着实现必须选择某种行为并提供文档。 未明确意味着实现必须选择某种行为但不必提供文档。 未定义意味着任何事情都可能发生。标准在任何情况下都不强加需求; 前两种情况下, 它有时建议一组可能的行为 (也可能要求从中选择一种)。
注意既然标准对无定义行为没有强制要求, 编译器就绝对可以做 任何事情。特别地, 对程序其它部分的正常运行没有任何保证; 参见问题 3.2, 有一个相对简单的例子。

如果你对书写可移植代码有兴趣, 你可以忽略它们的区别, 因为通常你都 希望避免依赖三种行为中的任何一种。

参见问题 3.8 和 11.34。

第四种不那么严格定义的行为是 ``场景特定" (locale-specific)。

参考资料: [ISO, Sec. 3.10, Sec. 3.16, Sec. 3.17]; [Rationale, Sec. 1.6]。

热点排行