c - 这是未定义的行为吗
问题描述
据我了解,这个程序应该有未定义的行为。
#include <stdio.h>
int main()
{
int a = 3, b = 3, c = 10, d = 20;
int e = (a++ * ++b)-((c / b) * a) + d;
printf("%d", e) ;
return 0;
}
C99 标准 §6.5 ¶2 说
在前一个和下一个序列点之间,对象的存储值最多只能通过表达式的评估修改一次。此外,应仅读取先验值以确定要存储的值。
因此,在定义'e'
,a
和b
被读取的行中,不仅是为了确定要在a
and中存储什么b
,而且是为了计算表达式((c / b) * a)
但是,即使使用 .gcc 也不会发出警告-Wsequence-point warning
。
我在这里想念什么?
解决方案
使用 clang 编译器(版本 - clang-1001.0.46.4)编译时,收到以下警告:
p.c:6:19: warning: unsequenced modification and access to 'b' [-Wunsequenced]
int e = (a++ * ++b)-((c / b) * a) + d;
^ ~
p.c:6:14: warning: unsequenced modification and access to 'a' [-Wunsequenced]
int e = (a++ * ++b)-((c / b) * a) + d;
^ ~
来自 C11 Standards#6.5p2 [强调添加]
2如果标量对象上的副作用相对于同一标量对象上的不同副作用或使用同一标量对象的值的值计算是未排序的,则行为未定义。如果一个表达式的子表达式有多个允许的排序,则如果在任何排序中出现这种未排序的副作用,则行为未定义。84)
该表达式调用未定义的行为。
编辑:
带有 标记的问题gcc
,因此为了完整回答,下面是使用gcc
带有-Wall
选项的编译器编译时的输出:
p.c:6:19: warning: operation on 'b' may be undefined [-Wsequence-point]
int e = (a++ * ++b)-((c / b) * a) + d;
^
p.c:6:14: warning: operation on 'a' may be undefined [-Wsequence-point]
int e = (a++ * ++b)-((c / b) * a) + d;
^
请注意,如果我们在编译时没有指定任何选项(如-Wall
or -Wsequence-point
)gcc
,则不会对有问题的表达式给出任何警告消息,但clang
编译器并非如此。
推荐阅读
- c - 计算和打印矩阵的对角线之和
- javascript - 如何在 Angular 中使用 addEventListener 和 postMessage?
- php - 如何将日期、时间和值从单选按钮放入数据库
- c# - 逐个像素地动态绘制和显示,有一些延迟
- npm - 如何从 Nexus oss 代理获取依赖于 github 项目的 npm 包
- django - Django 测试 - 发送包含整数的数组数组
- android - 在 android 中使用改造登录
- json - 我如何在 nunjuncks 中乘以数据?
- swift - 为什么不能在swift中将可变参数标记为inout?
- vue.js - Vue Js 2 / Vue-CLI 3 / 托管时显示空白页