C и C++. Pointer(int*) to int

248
13 декабря 2017, 23:40

Вот код в C++

#include <iostream>
using namespace std;
int a;
int* b;
int main()
{
    int d = 5;
    b = &d;
    a = (int)b;
    return 0;
}

И вот тот же код в C

#include <stdio.h>
int a;
int* b;
int main()
{
    int d = 7;
    b = &d;
    a = (int)b;
} 

Почему тот же самый код работает в C и не работает в C++. И как в C происходит преобразование int* to int

Answer 1

И в С, и в С++ результирующее значение преобразования указательного типа к целочисленному определяется реализацией. Однако:

  • В языке С++ преобразование указательного типа в целочисленный тип делается в соответствии со спецификацией reinterpret_cast. Спецификация reinterpret_cast явным образом говорит, что преобразование указательного типа в целочисленный тип допускается только если целочисленный тип обладает достаточным размером, для того, чтобы хранить результирующее значение. В вашем случае, очевидно, получилось так, что тип int не в состоянии хранить результат преобразования указателя типа int * к целочисленному типу. Поэтому код ошибочен.

  • В языке С преобразование указательного типа в целочисленный тип не требует того, чтобы целочисленный тип был достаточно большим. Спецификация языка лишь говорит, что в случае недостаточного размера целочисленного типа поведение не определено.

Если предположить, что ваши С++ и С платформы обладают одинаковыми характеристиками типов int * и int и тип int слишком узок для хранения результата данного преобразования, то ваша программа является некорректной (ill-formed) с точки зрения С++. И при этом является корректной, но ведущей себя неопределенно с точки зрения С. (Последнее говорит о том, что ни о каком "работает в C" в данном случае не может быть и речи, какой бы вы смысл ни вкладывали в слово "работает".)

Также можно заметить, что допустимые проявления неопределенного поведения включают и отказ компилятора компилировать код, содержащий неопределенное поведение. То есть при желании компилятор языка С имеет полное право реагировать на этот код точно так же, как отреагировал в вашем случае компилятор языка С++.

И, вдогонку, удивляет сама постановка вопроса про "почему тот же самый код работает в C и не работает в C++". С и С++ - сильно разные языки. Поэтому не ясно почему тот факт, что "тот же самый код работает в C и не работает в C++", вызывает вопросы.

Answer 2

То что вы написали - это приведение типов. В общем тут вообще не понятно зачем этот код нужен? Дело в том, что неразыменованный указатель - это адрес ячейки памяти (8-ми байтовое число, как правило. Когда вы делаете (int) b - вы просто урезаете его до 4 байт. Подобное приведение типов в С++ не разрешено (в таком виде).

READ ALSO
multiple definition of помогите [дубликат]

multiple definition of помогите [дубликат]

На данный вопрос уже ответили:

245
помогите пожалуйста с массивом [требует правки]

помогите пожалуйста с массивом [требует правки]

Дан одномерный массив, состоящий из  вещественных элементовНайти сумму элементов массива, расположенных между первым и вторым отрицательными...

253
Выбор компилятора C++ в Windows

Выбор компилятора C++ в Windows

Посоветуйте, пожалуйста, компилятор C++ для Windows, чтобы его можно было использовать в таких программах как CLion, CodeBlocks и Geany

237
Удаление лишних пробелов из строки

Удаление лишних пробелов из строки

Как сделать пропуск лишних пробелов для введенного текста? Получилось написать для заданного

193