2010-08-11 2 views
5

Несколько простых вопросов.Порядок данных в памяти

const int gFirst; 
const int gSecond; 

struct Data 
{ 
    static int First; 
    static int Second; 

    int first; 
    int second; 
}; 

Data data; 

Гарантировано, что следующие утверждения верны?

  1. &gFirst < &gSecond
  2. &Data::First < &Data::Second
  3. &data.first < &data.second

ответ

8

1) Этот результат не определен.
2) Этот результат неуточнен. *
3) Да.

Соответствующий раздел в стандарте - §5.9/2. Реляционные сравнения между указателями p и q рассчитаны только в следующих случаях:

  • p и q указывают на тот же объект или функцию точки к одной мимо конца того же массива, или оба равны нулю. В этом случае действительны p <= q и p >= q, а p < q и p > q являются ложными.
  • p и q указывают на нестатические элементы данных того же объекта, указатель на более поздний объявленный элемент сравнивается больше. (Обратите внимание, что это сравнение не может быть между спецификаторами доступа.)
  • p и q указывают на элементы внутри одного массива или один за концом массива, указатель на элемент с более высоким индексом или один за концом массив сравнивается больше.
  • p и q указывают на элементы данных одного и того же объекта объединения, и в этом случае они сравнивают одинаковые значения.

Во всех остальных случаях результат не указан.

* Поскольку они являются статическими, они (очевидно) не получают правила «нестатического члена». Они будут определены в некоторой единицы перевода и, следовательно, точно так же, как и любой другой указатель. (Неизвестно.)


Примечание! Существует способ, чтобы получить полный порядок, и это через std::less<void*>

Это в §20.3.3/8 (и всех других сравнительных функциональных объектов.):

Для шаблонов greater, less , greater_equal и less_equal, специализации для любого типа указателей дают общий порядок, даже если встроенные операторы <, >, <=10, >= нет.

Так что пока вы не знаете, если std::less<void*>(&gFirst, &gSecond) является true или false, вы гарантированно:

std::less<void*>(&gFirst, &gSecond) == 
    std::greater<void*>(&gSecond, &gFirst); 
std::less<void*>(&Data::First, &Data::Second) == 
    std::greater<void*>(&Data::Second, &Data::First); 

который может оказаться полезным.

6

ответ:

1) Not guaranteed. 
    But probably. 
    But the order of initialization is guaranteed. 
2) No. 
    You just have the declaration here. 
    You need to to define the instances in a source file. 
    Then they will behave the same way as the objects in (1). 
3) Yes. 
+0

To 1) Я думаю, что порядок инициализации внутри одного исходного файла гарантирован. Порядок инициализации нескольких файлов Sourcefiles не определен. –

+0

Я был неаккуратен с вопросом 2, предполагая, что вы также инициализируете данные в другом файле в том же порядке, что и переменные, объявленные здесь. Виноват. Этот 2. случай на самом деле тот, которого я больше всего интересую. – zeroes00

Смежные вопросы