首页 > 后端开发 > C++ > C 中 `i = i` 总是未定义行为吗?

C 中 `i = i` 总是未定义行为吗?

Patricia Arquette
发布: 2024-12-07 03:00:11
原创
886 人浏览过

Is `i  =   i` Always Undefined Behavior in C  ?

重新审视未定义的行为和序列点

内置类型的未定义行为

在上一部分中,“未定义的行为和序列点”我们讨论了与相关的潜在未定义行为表达式:

i += ++i;
登录后复制

当 i 是内置类型时,此表达式会调用未定义的行为,因为对象 i 在连续序列点之间被修改两次。

用户定义类型的未定义行为

但是,如果i是用户自定义类型,比如定义的Index类下面:

class Index
{
    int state;

    public:
        Index(int s) : state(s) {}
        Index& operator++()
        {
            state++;
            return *this;
        }
        Index& operator+=(const Index & index)
        {
            state+= index.state;
            return *this;
        }
        operator int()
        {
            return state;
        }
        Index & add(const Index & index)
        {
            state += index.state;
            return *this;
        }
        Index & inc()
        {
            state++;
            return *this;
        }
};
登录后复制

表达式 i = i 是否仍然会调用未定义的行为?

重载运算符的明确定义的行为

令人惊讶的是,不会。具有用户定义类型 i 的表达式 i = i 不会调用未定义的行为,因为重载运算符被视为 C 中的函数。根据 C ISO 标准第 1.9.17 节:

调用函数时(无论函数是否内联),在所有函数参数求值之后都有一个序列点...

因此,对运算符和运算符 = 函数的调用会引入序列点,从而防止未定义的行为。

a[ i] = 的未定义行为i

当 a 是带有重载下标运算符的用户定义类型时,表达式 a[ i] = i 也是明确定义的,因为在评估 i 表达式后,它被视为带有序列点的函数调用.

i 的明确定义行为

在 C 03 中,表达式 i 是明确定义的,因为它实际上是等价的to:

((i.operator++()).operator++()).operator++();
登录后复制

每个函数调用都会引入一个序列点,使表达式定义良好。

以上是C 中 `i = i` 总是未定义行为吗?的详细内容。更多信息请关注PHP中文网其他相关文章!

来源:php.cn
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板