在C ++中增加常量 [英] Incrementing a Constant in C++

查看:151
本文介绍了在C ++中增加常量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有人可以向我解释为什么此代码有效吗?我觉得编译器不应该允许我做我已经做过的事情(移动一个int指针指向const int),或者我至少希望编译器发出警告或出现段错误.更改常量值的想法似乎太错误了.

Can someone explain to me as why this code works? I feel like the compiler should not allow me to do what I have done (move an int pointer to point at a const int), or alternatively I would at least expect a compiler warning or a segfault. The idea of changing the value of a constant just seems so wrong.

代码:

#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

推荐答案

您的程序通过两种方式调用未定义行为,这意味着程序的行为是无法预测的,甚至看似正常的行为也是可能的.

You program invokes undefined behavior in two ways, which means the behavior of your program is unpredictable, even seemingly normal behavior is possible.

首先,虽然我们可以将结构体的各个元素视为数组,但是一旦增加指针,它就不再是有效的解引用对象,它甚至不必指向很可能指向的下一个元素填充.

First although we can treat the individual elements of a struct as arrays once you increment the pointer it is no longer valid to dereference it, it does not not even have to be pointing to the next element it could very well be pointing to padding.

第二,尝试以未定义的行为更改const. 草稿C ++标准部分7.1.6.1 cv-qualifiers 4 段,内容为:

Second, attempting to alter a const in also undefined behavior. The draft C++ standard section 7.1.6.1 The cv-qualifiers paragraph 4 which says:

[...]在const对象的生存期(3.8)内进行任何修改都会导致未定义的行为.

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

我们可以从指针5.7 加法运算符看到,出于指针算术目的,非数组变量被视为一个元素的数组,

We can see for the purposes of pointer arithmetic a non-array variable is treated as an array of one element, from section 5.7 Additive operators which says:

出于这些运算符的目的,指向非数组对象的指针 行为与指向的数组的第一个元素的指针相同 长度为1,以对象的类型为其元素类型.

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.

并且从同一节开始,取消引用数组末尾是未定义的行为:

and furthermore dereferecing one past the end of an array is undefined behavior, from the same section:

将具有整数类型的表达式添加或减去时 从指针开始,结果具有指针操作数的类型. [...] 如果指针操作数和结果都指向 相同的数组对象,或者在数组对象的最后一个元素之后, 评估不得产生溢出;否则,行为 是未定义的.

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 一元运算符部分进一步了解:

we can further see from section 5.3.1 Unary operators which says:

一元*运算符执行间接操作:它所指向的表达式 应用应该是指向对象类型的指针,还是指向对象类型的指针. 函数类型,结果是一个引用该对象的左值,或者 功能

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

当我们取消引用我们期望的指针和 object 时,一旦结束,我们就不能保证拥有该指针.

when we dereference a pointer we expect and object which we are not guaranteed to have once we are one past the end.

GNU C ++库具有易于访问的解释,该解释为(强调我的):

The The GNU C++ Library has an easier to access explanation which says (emphasis mine):

您只能取消引用指向数组的指针.如果你的 数组指针指向数组外部-甚至指向 结束-您取消引用它,就会发生坏事.

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 ++中增加常量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆