Является ли "0xffffffff00000000" признаком смешения 32-битных и 64-битных компиляций? - PullRequest
11 голосов
/ 14 июля 2011

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

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

---- 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, укажите это. Иначе обсуждение «ноль» - это замечательное обсуждение, но неуместное в этой теме.

---- End-Edit ----

Ответы [ 2 ]

10 голосов
/ 14 июля 2011

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


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

Использование 0 для обозначения «нулевого указателя», возможно, является неудачным соглашением;уровень путаницы, который он вызывает, возможно, лучше всего обозначен продолжительностью C * FAQ по 1013 * на языке программирования Стива Саммита по этому вопросу.

Комментарий гекса, я думаю, свидетельствует о сложности понимания этогоусловность.Проблема в том, что нужно разделить три идеи:

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

Вот стандарт C ++, раздел 4.10:

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

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

0 голосов
/ 14 июля 2011

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...