C++ Преобразование из const int* в int *, работающее с неожиданными результатами

В C++ мы знаем, что мы не можем конвертировать const int * в int *. Но у меня есть фрагмент кода, где я могу конвертировать const int * в int *. Я новичок в C++, я гуглил по этому поводу, но я только что получил ссылки с упоминанием const int *, которые нельзя преобразовать в int *, чтобы избежать нарушения const. Я не могу понять, почему он компилируется без ошибок

#include <iostream>
using namespace std;

int main(void)
{
    const int a1 = 40;
    const int* b1 = &a1;
    int* c1 = (int *)(b1);
    *c1 = 43;
    cout<< c1<<" "<< &a1<<endl;
    cout<< *c1<<" "<< a1<<endl;
 }

Также проблема в выводе вышеприведенной программы:

0x7fff5476db8c 0x7fff5476db8c
43 40

Может кто-нибудь объяснить, почему целочисленный указатель c1 указывает на один и тот же адрес для a1, но имеет разные значения 43 и 40 соответственно.

4 ответа

В C++ объект является постоянным или нет. Если он постоянный, то любая попытка его изменения вызовет неопределенное поведение. Это то, что ты сделал. В этот момент все может случиться. Если вам повезет, он падает. Если вам повезет меньше, он будет работать до тех пор, пока ваш код не окажется в руках клиента, где он нанесет максимально возможный ущерб.

Вы можете легко преобразовать const int* в int * в C++. Ты только что сделал. Однако "const int*" и "int*" не означают, что указанная вещь является константной или нет. Это просто означает, что компилятор не позволит вам назначить в одном случае, и позволит вам назначить в другом случае. *c1 является const, Приведение указателя к int* не меняет того факта, что это const, Неопределенное поведение.

Это неопределенное поведение.

Но в этом случае произошло то, что компилятор понял, что он может заменить a1 в cout заявление с фактическим значением 40, потому что это должно быть const,

Никогда, никогда не полагайтесь на это, хотя. Это могло бы легко нанести татуировку вашей кошке.

const int переменная будет занимать память в стеке, но компилятор просто заменит весь экземпляр a1 с 40, Выражение &a1 не заменится, и как-то магическим образом указать на память в стеке. При изменении содержимого содержимое в памяти будет изменяться, но эти константы 40 не изменится. Следовательно, они отличаются по выходу.

Это не что иное, как неопределенное поведение и может отличаться от компилятора. Один компилятор может вызвать 43 для отображения, другой всегда может отображать 40 и некоторые другие могут генерировать код, вызывающий сбой (запись в постоянную память). Не делай этого!

Запустите это, может быть, это поможет.

const int a1 = 40;
std::cout<<"__________ const int a1 = 40; ____________________________________"<<std::endl;
std::cout<<"a1: "<< a1<<std::endl;
std::cout <<"&a1 "<< &a1<<std::endl;
std::cout <<"*a1: INVALID"<<std::endl;

const int* b1 = &a1;
std::cout<<"__________ const int* b1 = &a1; ____________________________________"<<std::endl;
std::cout<<"b1: "<< b1<<std::endl;
std::cout <<"&b1 "<< &b1<<std::endl;
std::cout <<"*b1 "<< *b1<<std::endl;

int* c1 = (int *)(b1);
std::cout<<"__________ int* c1 = (int *)(b1); ____________________________________"<<std::endl;
std::cout<<"c1: "<< c1<<std::endl;
std::cout <<"&c1 "<< &c1<<std::endl;
std::cout <<"*c1 "<< *c1<<std::endl;

*c1 = 43;
std::cout<<"__________ *c1 = 43; ____________________________________"<<std::endl;
std::cout<<"c1: "<< c1<<std::endl;
std::cout <<"&c1 "<< &c1<<std::endl;
std::cout <<"*c1 "<< *c1<<std::endl;

std::cout<<"c1: "<< c1<<std::endl;
std::cout<<"*c1: "<< *c1<<" -----> *&a1: "<< *&a1<<" - a1: "<< a1<<std::endl;
std::cout<<"&c1: "<< &c1<<std::endl;
Другие вопросы по тегам