Constant increase in C ++

Can someone explain to me why this code works? I feel that the compiler should not let me do what I did (move the int pointer to point to const int), or, alternatively, I would expect you to see a compiler warning or segfault. The idea of ​​changing the value of a constant just seems wrong.

the code:

#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; } 

Conclusion:

 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 
+5
source share
3 answers

A program performs undefined behavior in two ways, which means that the behavior of your program is unpredictable, even normal behavior is possible.

First, although we can treat individual elements of the structure as arrays after you increase the pointer, it is no longer suitable for dereferencing it, it should not even point to the next element, which it could well point to the upholstery.

Secondly, an attempt to change the constant also in undefined behavior. draft C ++ 7.1.6.1 Qualifying cv classifiers, which states:

[...] any attempt to change the const object during its lifetime (3.8) leads to undefined behavior.

We can see that for the purpose of pointer arithmetic, a variable without an array is considered as an array of one element from Section 5.7 Additive Operators, which states:

For the purposes of these operators, a pointer to a nonarray object behaves in the same way 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, splitting to one end of the end of the array is undefined behavior, from the same section:

When an expression with an integral type is added or subtracted from the pointer, the result has the type of the operand of the pointer. [...] If both the pointer operands and the result point to elements of the same array object or one after the last element of the array object, the evaluation should not lead to overflow; otherwise, the behavior is undefined.

we can see from Section 5.3.1 Unary operators that say:

The unary * operator performs an indirect direction: an expression to which it applies a pointer to the type of an object or a pointer to a type of a function and the result of an lvalue related to the object or Function

when we are looking for a pointer that we expect and an object that we do not guarantee when we are one after another.

The GNU C ++ library has easier access to an explanation that says (attention):

You can only dereference a pointer pointing to an array. If your array pointer points are outside the array - even to one end - and you look for it, Bad things.

+18
source

(This answer is correct for Visual Studio 2010 - not sure about other compilers.)

This is why it is allowed:

The const modifier is a compiler instruction that prevents the user from editing this declared variable. When working with this variable, the compiler will not allow you to make changes to it and requires you to add the const modifier to the pointers associated with this particular variable.

However, like other variable values, it is in memory, and the compiler does not prohibit access to this memory or its editing. It can be retrieved and changed in the same way as any other memory address, using a pointer if you decide to undermine the compiler instructions, as it was in your code.

If you want to prevent access to programs in areas in memory, you can refer to the following memory protection constants for Windows:

http://msdn.microsoft.com/en-us/library/windows/desktop/aa366786(v=vs.85).aspx

+1
source

data elements in the structure are stored in the stack in memory, so when you create a pointer and point to the first element, the address that is stored is the position of the stack pointer. When u increases its stack, the pointer increases to the next place on the stack, i.e. second data item. thus, this may be a possible cause. Because otherwise it had to give an error, and also we cannot consider the structure as an array. Bt can still point to the next element, perhaps only if we look at the stack created in memory.

-1
source

Source: https://habr.com/ru/post/1203747/


All Articles