Ни одно из неопределенного, определенного реализацией, неопределенного поведения
C++ 03
$ 5.3.3 / 2 - "Размер наиболее производного класса должен быть больше нуля (1,8)".
$1.8/4 - "Если это не битовое поле (9.6), наиболее производный объект должен иметь ненулевой размер и занимать один или несколько байтов памяти".
Тогда мой вопрос:
Не определен ли размер пустого класса, определена реализация? Это должно быть задокументировано в документации компилятора? Эти две цитаты оставляют его настолько открытым, насколько я понимаю.
2 ответа
Это не указано (за исключением того, что оно должно быть больше 0). Он также не определен реализацией (поэтому его не нужно документировать).
Я не уверен, почему реализация будет использовать любой размер, отличный от 1, для пустого класса (предполагая, что под "пустым классом" мы говорим о классе, который даже не является производным от другого класса), но я полагаю, что это возможно.
Чтобы ответить на вопрос Чубсдада о том, что определяет, что это неопределенное поведение (в отличие от определенной реализации):
Стандарт определяет "неопределенное поведение" как:
поведение, для правильно сформированной программы построить и исправить данные, это зависит от реализации. Реализация не обязана документировать, какое поведение происходит.
Он определяет "поведение, определяемое реализацией" как:
поведение, для правильно сформированной программы построить и исправить данные, которые зависят от реализации и что каждая реализация должна документировать
Таким образом, единственное различие между ними заключается в том, что поведение, определяемое реализацией, должно быть задокументировано. Стандарт скажет, когда поведение должно быть задокументировано (обычно, говоря, что поведение определяется реализацией)
К сожалению, стандарт не всегда прямо заявляет, что поведение не определено (или не определено). Итак, некоторый анализ в порядке:
Поскольку стандарт гласит:
- тот
sizeof
должен оценить результат больше нуля для пустого класса, - не говорит, что это значение должно быть (кроме больше нуля)
- не говорит, что значение должно быть задокументировано (или что оно определяется реализацией)
в процессе исключения размер пустого класса не указывается.
Возможная проблема с этим анализом (и с большим количеством анализа чего-то такого сложного, как стандарт C++) заключается в том, что существует вероятность того, что есть какой-то другой угол стандарта, который я пропустил, который может потребовать, чтобы размер пустого класса был каким-то конкретным значением, И это требование может быть выведено (или будет выводом) из некоторых других правил; это не может быть указано прямо. Не всегда легко отследить все области стандарта, которые могут относиться к конкретной проблеме.
Если это так, то, надеюсь, кто-то заметит это и отразит мою аргументацию.
Наиболее производный тип означает класс полного объекта типа класса (1.8 стандарта C++ (intro.object)). Таким образом, пустой класс, который создается, должен иметь уникальный адрес, что подразумевает, что sizeof(empty class)>0
, Однако это также означает, что у вас может быть базовый класс нулевого размера (также в 1.8 стандарта C++).
Так что если вам нужно создать экземпляр пустого класса, он не может иметь нулевой размер. Если это подобъект базового класса, то он может иметь нулевой размер.