Можно ли получить указатель на один подобъект через указатель на другой, не связанный объект?

Посмотрите на этот простой код:

struct Point {
    int x;
    int y;
};

void something(int *);

int main() {
    Point p{1, 2};

    something(&p.x);

    return p.y;
}

Я ожидаю, что возвращаемое значение main может быть оптимизировано до return 2;, так как something не имеет доступа к p.y , он получает только указатель на p.x.

Но ни один из основных компиляторов не оптимизирует возвращаемое значение от main до 2. Godbolt .

Есть ли в стандарте что-то, что позволяет something модифицировать p.y, если мы только даем доступ к p.x? Если да, зависит ли это от того, имеет ли Point стандартное расположение?

Что если я использую something(&p.y); и return p.x; вместо этого?

51
задан curiousguy 18 September 2019 в 02:22
поделиться

1 ответ

Это совершенно четко определено:

void something(int *x) {
    reinterpret_cast<Point*>(x)->y = 42;
}

Point объект (p) и x участник являются взаимозаменяемыми указателем, от [basic.compound]:

Два объекта и b взаимозаменяемые указателем если:

  • [...]
  • каждый - объект стандартного класса макета, и другой первый нестатический элемент данных того объекта, или, если объект не имеет никаких нестатических элементов данных, какого-либо подобъекта базового класса того объекта ([class.mem]), или:
  • [...]

, Если два объекта являются взаимозаменяемыми указателем, то у них есть тот же адрес, и возможно получить указатель на один от указателя до другого через reinterpret_­cast.

, Что reinterpret_cast<Point*>(x) допустимо и действительно заканчивается с указателем, который указывает на p. Следовательно, изменение это непосредственно прекрасно. Как Вы видите, часть стандартного расположения и первая нестатическая часть элемента данных являются значительными.

<час>

, Хотя это не похоже на рассматриваемые компиляторы, оптимизируют дополнительную загрузку, если Вы передаете указатель на p.y в и возврат p.x вместо этого.

51
ответ дан 7 November 2019 в 10:21
поделиться
Другие вопросы по тегам:

Похожие вопросы: