[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

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: