Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

The order of data in memory

A few simple questions.

const int gFirst;
const int gSecond;

struct Data
{
    static int First;
    static int Second;

    int first;
    int second;
};

Data data;

Is it guaranteed that the following statements are true?

  1. &gFirst < &gSecond
  2. &Data::First < &Data::Second
  3. &data.first < &data.second
like image 211
zeroes00 Avatar asked Aug 11 '10 06:08

zeroes00


1 Answers

1) This result is unspecified.
2) This result is unspecified.*
3) Yes.

The relevant section in the standard is §5.9/2. Relational comparisons between the pointers p and q are only specified when:

  • p and q point to the same object or function, point to one past the end of the same array, or both are null. In this case, p <= q and p >= q are true, and p < q and p > q are false.
  • p and q point to nonstatic data members of the same object, the pointer to the later declared member compares greater. (Note, this comparison cannot be between access specifiers.)
  • p and q point to elements within the same array or one past the end of the array, the pointer to the element with the higher subscript or to one past the end of the array compares greater.
  • p and q point to data members of the same union object, in which case they compare equal.

In all other cases, the result is not specified.

*Because they are static, they (obviously) do not get the "nonstatic member" rules. They will be defined in some translation unit, and therefore are just like any other pointer. (Unspecified.)


Note! There is a way to get total ordering, and that is via std::less<void*> (and all the other comparative function objects.)

This is in §20.3.3/8:

For templates greater, less, greater_equal, and less_equal, the specializations for any pointer type yield a total order, even if the built-in operators <, >, <=, >= do not.

So while you don't know if std::less<void*>(&gFirst, &gSecond) is true or false, you are guaranteed:

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

Which can prove useful.

like image 138
GManNickG Avatar answered Oct 21 '22 02:10

GManNickG