Является ли "0xffffffff00000000" индикатором смешения между 32-битными и 64-битными компиляциями?

Я скомпилировал Qt в 64 бит. Мой код также скомпилирован в 64 бит. Я инициализирую переменную-член (указатель) до нуля. Когда я проверяю его, XCode сообщает мне, что его значение не равно 0, а 0xffffffff00000000.

Является ли это признаком переполнения между 32 и 64? Каким образом 32-разрядная инициализация закралась в исполняемый файл, когда и библиотека, и мой код имеют "g++.. -arch x86_64 -Xarch_x86_64.."? В случае, если это имеет значение, я на Snow Leopard.

---- Begin-Edit ----

Я благодарен за все эти годы, что стандарт не налагает значение 0x00..00, когда присваивается 0 указателю, но в этом случае это не проблема.

#include <stdio.h>

int main()
{
    const char * c = "Foo";
    printf("Pointers in this executable use %lu bytes.\n", sizeof(c));
    void * z = 0;
    printf("A zero pointer in this executable is %p\n", z);
}

Если я сохраню код выше в "32_or_64.cpp", тогда скомпилируйте его с помощью "g++ -arch i386 32_or_64.cpp", я получаю

Pointers in this executable use 4 bytes.
A zero pointer in this executable is 0x0

Если я скомпилирую его с помощью 'g++ -arch x86_64 32_or_64.cpp', я получаю

Pointers in this executable use 8 bytes.
A zero pointer in this executable is 0x0

Если вы считаете, что это не устанавливает, что 0 в моей конкретной конфигурации не должно позволять мне видеть точно 0 при отладке в x86_64, пожалуйста, укажите это. В противном случае обсуждение "null" - замечательное обсуждение, но не относящееся к делу в этом потоке.

---- End-Edit ----

Ответ 1

Обновить: это объяснение кажется фиктивным в свете редактирования. Но вам все равно может показаться интересным.


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

Использование 0 означает "нулевой указатель", возможно, является неудачным соглашением; уровень замешательства, который он вызывает, возможно, лучше всего указывается в тексте

C на языке программирования .

hexa comment, я думаю, свидетельствует о трудностях понимания этого соглашения. Беда в том, что есть три идеи, которые нужно разделить:

  • Концепция нулевого указателя: указатель, отличный от указателя на любой объект.
  • Представление нулевого указателя на машине (в некоторых случаях по адресу 0x00000000, но это не то, на что вы можете или должны полагаться).
  • Как вы можете создавать и проверять нулевые указатели на языках C-типа (используя константу нулевого указателя, такую ​​как 0 или NULL).

Здесь стандарт С++, раздел 4.10:

Константа нулевого указателя представляет собой интегральное постоянное выражение rvalue целочисленного типа, которое вычисляется до нуля. Константа нулевого указателя может быть преобразована в тип указателя; результатом является нулевое значение указателя этого типа и отличается от любого другого значения указателя на объект или указателя на тип функции. Два значения нулевого указателя одного и того же типа сравниваются равными.

Это гарантирует, что вы можете создать нулевой указатель, используя константу 0, и проверить, является ли указатель нулевым по сравнению с 0, но ничего не говорит о машинном представлении нулевого указателя.

Ответ 2

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