Почему 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?


person Jim Hunziker    schedule 03.05.2012    source источник
comment
Я считаю, что мой вопрос является дубликатом этого: wtf-на-линукс   -  person Jim Hunziker    schedule 03.05.2012


Ответы (1)


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

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

  1. net/if.h включает features.h
  2. Позже он определяет struct ifreq внутри блока #ifdef __USE_MISC.

So:

  1. Что такое __USE_MISC? -- это общие вещи для BSD и System V
  2. На данный момент это определено? -- Нам нужно проверить это в features.h

Итак, features.h:

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

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

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

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

или различать их любым другим способом (например, diff --side-by-side) вместо vimdiff.

Если вы хотите, чтобы это правильно скомпилировалось с -std=c99, вы должны рассмотреть возможность включения макроса тестирования функций _DEFAULT_SOURCE (для версий glibc >= 2.19; для более старых версий glibc используйте либо _BSD_SOURCE, либо _SVID_SOURCE), чтобы требуемая функциональность была включена поверх что предлагает C99.

person ArjunShankar    schedule 03.05.2012
comment
Спасибо за объяснение. Я только что наткнулся на точно такую ​​​​же проблему. Есть ли способ успешно скомпилировать такой код с помощью --std=c99? - person michas; 16.07.2014
comment
@michas Да. Вы можете определить _BSD_SOURCE или _SVID_SOURCE макрос тестирования функций в ваших исходных текстах C. - person ArjunShankar; 16.07.2014