gpt4 book ai didi

c++ - 在 C++ 中递增常量

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:52:31 25 4
gpt4 key购买 nike

有人可以向我解释为什么这段代码有效吗?我觉得编译器不应该允许我做我所做的事情(移动一个 int 指针指向一个 const int),或者我至少会期待编译器警告或段错误。改变常量值的想法似乎是错误的。

代码:

#include <iostream>

using namespace std;

struct test_struct {
int i;
const int j;
};

int main() {
cout << "Create a struct with int i = 100 and const int j = 101." << endl;
test_struct test{100, 101};
cout << test.i << endl;
cout << test.j << endl;
cout << "Create pointer p and point it to int i." << endl;
int* p1 = &test.i;
cout << *p1 << endl;
cout << "Increment pointer p, which should now be pointing at const int j." << endl;
p1++;
cout << *p1 << endl;
cout << "Dereference p and increment it." << endl;
(*p1)++;
cout << *p1 << endl;
cout << test.j << endl;
}

输出:

Create a struct with int i = 100 and const int j = 101.
100
101
Create pointer p and point it to int i.
100
Increment pointer p, which should now be pointing at const int j.
101
Dereference p and increment it.
102
102

最佳答案

你的程序调用了undefined behavior有两种方式,这意味着您的程序的行为是不可预测的,即使看似正常的行为也是可能的。

首先,虽然我们可以将结构的各个元素视为数组,但一旦您递增指针,取消引用它就不再有效,它甚至不必指向它很可能指向的下一个元素填充。

其次,试图在同样未定义的行为中改变常量。 draft C++ standard 7.1.6.1 The cv-qualifiers4 说:

[...]any attempt to modify a const object during its lifetime (3.8) results in undefined behavior.

我们可以看到,出于指针运算的目的,非数组变量被视为一个元素的数组,来自 5.7 Additive operators 部分,它说:

For the purposes of these operators, a pointer to a nonarray object behaves the same as a pointer to the first element of an array of length one with the type of the object as its element type.

此外,在同一节中取消对数组末尾的引用是未定义的行为:

When an expression that has integral type is added to or subtracted from a pointer, the result has the type of the pointer operand. [...] If both the pointer operand and the result point to elements of the same array object, or one past the last element of the array object, the evaluation shall not produce an overflow; otherwise, the behavior is undefined.

我们可以从 5.3.1 一元运算符 部分进一步看出:

The unary * operator performs indirection: the expression to which it is applied shall be a pointer to an object type, or a pointer to a function type and the result is an lvalue referring to the object or function

当我们取消引用我们期望的指针和对象时,我们不能保证一旦我们过了最后就拥有。

The GNU C++ Library有一个更容易理解的解释,上面写着(强调我的):

You can only dereference a pointer that points into an array. If your array pointer points outside the array -- even to just one past the end -- and you dereference it, Bad Things happen.

关于c++ - 在 C++ 中递增常量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26128980/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com