Безопасно ли утверждать (sizeof (A) == sizeof (B)), когда A и B "одинаковы"? - PullRequest
18 голосов
/ 08 марта 2019

Предположим, у меня есть два класса, которые, как я ожидаю, будут иметь одинаковую структуру памяти:

struct A {
    int x;
    int y;
};

/* possibly more code */

struct B {
    int a;
    int b;
};

Есть ли в стандарте что-нибудь, что гарантирует, что я могу безопасно static_assert(sizeof(A) == sizeof(B))?

В качестве более слабого варианта рассмотрим

struct C {
    int a;
};

static_assert( sizeof(A) >= sizeof(C) );   // can this ever fail?
static_assert( sizeof(A) >  sizeof(C) );   // can this ever fail?

Вопрос был вызван этим . Наивно я не ожидал бы, что какое-либо из утверждений потерпит неудачу, но гарантировано ли это?

Ответы [ 3 ]

4 голосов
/ 09 марта 2019

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

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

3 голосов
/ 09 марта 2019

A Придумано Контрпример:

#include <stdint.h>

struct A {
    int32_t a;
    int64_t b;
};

#pragma pack(4)

struct B {
    int32_t a;
    int64_t b;
};

static_assert(sizeof(A) == sizeof(B));

Компиляция с g++ в 64-битном Linux дает:

a.cc:15:1: error: static assertion failed
static_assert(sizeof(A) == sizeof(B));
0 голосов
/ 08 марта 2019

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

Компилятор имеет только определение структуры, чтобы обработать смещение члена, поэтому, если вы не используете непротиворечивое расположение, вы не сможете получить доступ к структуре.

...