Размер структуры с гибким элементом массива

Дано

struct Foo {
    uint32_t a;
    uint32_t b[];
};

Что такое sizeof(Foo)? Это поведение, определяемое реализацией или неопределенное? Различается ли ответ для C и C++?


person Timmmm    schedule 19.07.2017    source источник
comment
FWIW VLA не являются стандартными в C++, поэтому все, что вы получите, будет определяться реализацией.   -  person NathanOliver    schedule 19.07.2017
comment
port70.net/~nsz/c/c11/n1570.html #6.7.2.1p18   -  person Eugene Sh.    schedule 19.07.2017
comment
@Olaf Почему ты удалил тег C++? Вопрос в том, что C против C++. Разве это не законно и не разумно?   -  person Scheff's Cat    schedule 19.07.2017
comment
Простой взгляд на стандарт сэкономил бы время.   -  person too honest for this site    schedule 19.07.2017
comment
@Scheff Очевидно, вопрос относится только к одному из разных языков.   -  person too honest for this site    schedule 19.07.2017
comment
@Scheff Я думаю, что это не незаконно. Но лучше иметь два разных вопроса, так как здесь много экспертов по C и много экспертов по C++, которые не всегда являются одними и теми же людьми. Часть C ++ была причиной, по которой я поместил ссылку на стандарт C в комментарий и не сделал ее ответом, поскольку у меня нет ее в голове о C ++ .   -  person Eugene Sh.    schedule 19.07.2017
comment
@Olaf Для меня это было не так очевидно (хотя мой желудок мешал мне сделать что-то подобное на C ++), но я вижу ваше намерение.   -  person Scheff's Cat    schedule 19.07.2017
comment
Это противоречит вопросу, в котором явно задается вопрос о различиях между C и C++ (и ответ касается этого) → тег восстановлен.   -  person    schedule 19.07.2017
comment
Одже... (Мир, пожалуйста.)   -  person Scheff's Cat    schedule 19.07.2017
comment
Он работает на C++ как в Clang, так и в GCC, поэтому на вопрос можно ответить. Ответ может быть: Это не стандарт, но поддерживается, но GCC и Clang. На этих компиляторах размер равен 4. Это полезная информация.   -  person Timmmm    schedule 19.07.2017
comment
Даже не уверен, зачем нужно задавать вопрос - достаточно легко узнать, каким будет sizeof, с помощью простого вызова printf   -  person Chris Turner    schedule 19.07.2017
comment
@Scheff: Должно быть, какая-то немецкая штучка…   -  person too honest for this site    schedule 19.07.2017
comment
@ChrisTurner: Потому что C/C++ полон неопределенного и определяемого реализацией поведения. printf тебе этого не скажет.   -  person Timmmm    schedule 19.07.2017
comment
Да, лучше не судите так о качестве вопроса. Стандартные документы не совсем легко читать, вы должны быть уже хорошо знакомы с ними, чтобы найти то, что ищете. И судя по всему, вопрос хорошо принят. Дубликат не идеален, но, поскольку был дан ответ, что FAM просто не существуют в С++, это нормально в качестве ссылки на сильно связанный вопрос.   -  person    schedule 19.07.2017
comment
@Timmmm: Мы можем судить только по тому, что было представлено в вопросе. И из этого видно, что вы вообще не занимались исследованиями.   -  person too honest for this site    schedule 19.07.2017
comment
Я не думаю, что это точный обман, так как этот вопрос касается С++ вместе с тегом c. Переоткрыл.   -  person haccks    schedule 19.07.2017
comment
ОБЯЗАТЕЛЬНО просмотрите этот ответ на Изменяемые члены массива могут привести к неопределенному поведению?   -  person chux - Reinstate Monica    schedule 19.07.2017


Ответы (1)


Компилятор проигнорирует гибкий элемент массива, поскольку его там нет.

C11-§6.7.2.1 (p18)

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

AFAIK, гибкий элемент массива не является частью стандарта С++ до С++ 14. Но GNU поддерживает его как расширение. . Поведение будет одинаковым как для C, так и для C++.

person haccks    schedule 19.07.2017
comment
Спасибо! На самом деле я не могу найти никаких упоминаний об этом в C++14, но я думаю, что можно с уверенностью предположить, что Clang/GCC/etc применяют к нему то же поведение в C++, что и в C (и по экспериментам они, кажется, ). - person Timmmm; 19.07.2017
comment
@феликс: struct { char a; double d[]; };. Если вы проигнорировали d, размер может быть 1. - person rici; 19.07.2017
comment
@rici да, это просто, но посмотрите здесь обсуждение;) (я просто вижу, что у меня может быть перепутал это с некоторыми другими цитатами... извините) - person ; 19.07.2017
comment
@felix Я видел это обсуждение ранее, но решил не вступать в драку. Стандарт C не предназначен для преднамеренного создания ложных ожиданий и не является своего рода Дельфийским оракулом, чьи таинственные высказывания могут быть разгаданы только высшими жрецами, искушенными в магических искусствах. Скорее, это описание языка программирования, предназначенного для использования (и пригодного для использования). Функция, описанная в стандарте, должна быть пригодной для использования; иначе его бы не было. Если формулировка делает это невозможным, это дефект и его следует исправить; это будет не первая и не последняя такая ошибка... - person rici; 19.07.2017
comment
... Вопрос, на который вы ссылаетесь, показался мне незаконным присвоением энергии: если аргумент OP действителен, его следует представить как DR комитету по стандартизации. Использование его вместо этого, чтобы воспрепятствовать использованию FAM, кажется мне тактикой человека, чьи эстетические чувства оскорблены FAM, и который поэтому считает, что их следует искоренить из языка. (Серьезный аргумент на этот счет тоже лучше было бы представить комитету, но я полагаю, что он не будет иметь успеха.) Теперь: какой интересный пример вы имели в виду? - person rici; 19.07.2017
comment
@rici Насколько я понял его комментарии, он действительно подготовил DR. Но я не уверен, что его аргументация верна ;) Отрывок в этом ответе просто напомнил мне, что я видел это обсуждение. - person ; 19.07.2017
comment
Давайте продолжим обсуждение в чате. - person rici; 19.07.2017