Почему C99 жалуется на размеры хранилища?

Это код, который я компилирую в Linux:

#include <net/if.h>

int main() {
  struct ifreq ifr;
}

gcc test.c отлично.

gcc -std=gnu99 test.c отлично.

gcc -std=c99 test.c выходит из строя со следующей ошибкой:

test.c: In function ‘main’:
test.c:4:16: error: storage size of ‘ifr’ isn’t known

Чем отличается от C99 то, что ему не нравится определение struct ifreq в Linux?

Ответ 1

Это цепочка последствий предварительной обработки и GNU C против C99.

Сначала, net/if.h:

  • net/if.h включает features.h
  • В дальнейшем он определяет struct ifreq внутри блока #ifdef __USE_MISC.

Итак:

  • Что такое __USE_MISC? - это обычное явление для BSD и System V
  • Определяется ли это на этом этапе? - Нам нужно проверить это в features.h

Итак, теперь features.h:

  • Когда вы используете --std=c99 GCC по умолчанию определяет __STRICT_ANSI__ (так как это означает, что C99)
  • При предварительной обработке features.h, когда __STRICT_ANSI__ включен, функции BSD и System V не срабатывают, т.е. __USE_MISC остается undefined.

Резервное копирование до net/if.h: struct ifreq даже не существует после предварительной обработки! Поэтому жалоба на размер хранилища.

Вы можете поймать всю историю, выполнив:

vimdiff <(cpp test.c --std=c99 -dD) <(cpp test.c --std=gnu99 -dD)

или иначе их отличить (например, diff --side-by-side) вместо vimdiff.