Re: Чёртов язык Си!
On Tue, 7 Oct 2014, Artem Chuprina wrote:
yuri.nefedov@gmail.com -> debian-russian@lists.debian.org @ Tue, 7 Oct 2014 14:15:27 +0400 (MSK):
y> В этом случае нельзя передавать массивы:
y> void f(struct S a[]) == void f(struct S* a)
y> так как sizeof(struct S) может поменяться.
y> Даже без обращения к полям.
Да, но из этого всего лишь следует, что API библиотеки не будет
содержать void f(struct S a[]).
Поскольку, не имея определения S, ты не сможешь в своей программе
самостоятельно создать оный массив, то оно тебе и не надо.
Надо сказать, что мне в моей довольно богатой программистской практике
ни разу не пришлось воспользоваться функцией с аргументом типа массив...
y> Это не возражение. Это уточнение.
y> Размер грабель неопределен.
Последней фразы я не понял.
В С нет разницы между void f(struct S a[]) и void f(struct S *a)
- компилятору это всё равно.
Моё беспокойство было, как будет обрабатываться a[i] или, что то же
самое *(a+i). Как компилятор предотвратит использование такой
конструкции?
Немножко подумав, пришел к выводу, что в этом месте
компилятору потребуется sizeof(struct S).
Наверное, поэтому sizeof и является оператором времени компиляции
и компилятор захочет полное определение структуры.
А вот если sizeof будет вызываться во время выполнения,
то и будут грабли.
Посмотрел стандарт C: когда выполняется sizeof() не описано.
Сказано только:
The sizeof operator shall not be applied to an expression that
has function type or an incomplete type, to the parenthesized name
of such a type, or to an expression that
designates a bit-field member.
Однако и gcc и clang такое вот разрешают:
printf("sizeof(*print_s)= %lu\n",sizeof(*print_s));
где print_s - это имя функции.
Так что "shall not be applied" на совести программиста.
Ю.
Reply to: