Мне не удается найти однозначный ответ на один мутный вопрос. Я перерыл три Стандарта, десяток книг, у коллег поспрашивал, вопрос не прояснился.
Ситуация такая.
Стандарты, кажется все, запрещают объявлять массивы нулевого размера:
int arr[0];
Всякие расширения во внимание не берем. Как я понял, запрет на массивы нулевого размера был введен для того, чтобы сохранить одно из фундаментальных требований языка, согласно которому разные объекты должны иметь разные адреса.
Но что, если мы имеем функцию:
void f(const size_t _count)
{
int arr[_count];
// ...
}
В общем, вопросы такие:
1) Это уже неопределенное поведение?
2) Или неопределенное поведение возникнет в тот самый момент, когда функцию вызовут с нулевым параметром?
3) Или же неопределенное поведение возникнет лишь в том случае, если произойдет обращение к элементу массива переменной длины с нулем элементов?
Тема актуальная, потому что я видел множество кода, в котором стараются эффективно использовать стек, используя массивы переменной длины, которые могут оказаться нулевого размера, но при этом не будут использоваться. Как пример - функция взаимодействия с промышленным оборудованием, в которой имеется несколько десятков массивов-буферов.
Конечно, в таких функциях можно использовать malloc(), но это очень дорого по времени.
Так же можно использовать int a[MAX_A], но это очень дорого по памяти - каждый вызов такой функции будет откусывать от стека огромный кусок, 99% которого не будет востребовано.
Ответ
Судя по ответу из англоязычного СО, это неопределённое поведение. Там приводится пункт стандарта 6.7.6.2§5:
If the size is an expression that is not an integer constant expression: if it occurs in a
declaration at function prototype scope, it is treated as if it were replaced by *; otherwise, each time it is evaluated it shall have a value greater than zero. (...)
То есть стандарт говорит, что выражение должно быть больше нуля.
Более того, Clang с UBSan'ом покажут, что это действительно UB:
vlazero.c:5:10: runtime error: variable length array bound evaluates to non-positive value 0
Комментариев нет:
Отправить комментарий