2012-05-03 18 views
10

To jest jakiś kod mam kompilacji w systemie Linux:Dlaczego C99 narzeka na rozmiary przestrzeni dyskowej?

#include <net/if.h> 

int main() { 
    struct ifreq ifr; 
} 

gcc test.c jest w porządku.

gcc -std=gnu99 test.c jest w porządku.

gcc -std=c99 test.c nie powiedzie się z powodu następującego błędu:

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

Czym różni się C99, że nie lubi definicję struct ifreq w systemie Linux?

+0

Wierzę, że moje pytanie jest duplikatem tego: http://stackoverflow.com/questions/3875197/std-c99-wtf-on-linux –

Odpowiedz

16

Jest to łańcuch konsekwencji preprocesingu i GNU C vs C99.

Najpierw, net/if.h:

  1. net/if.h obejmuje features.h
  2. Później definiuje struct ifreq wewnątrz #ifdef __USE_MISC bloku.

Więc:

  1. Co jest __USE_MISC? - to jest coś wspólnego dla BSD i Systemu V
  2. Czy jest to zdefiniowane w tym miejscu? - Musimy sprawdzić, w features.h

Więc teraz, features.h:

  1. Podczas korzystania --std=c99 GCC domyślnie definiuje __STRICT_ANSI__ (ponieważ to jest to co C99 IS)
  2. Podczas przerób features.h, gdy __STRICT_ANSI__ jest włączone, funkcje BSD i System V nie zaczynają działać. Oznacza to, że __USE_MISC jest niezdefiniowany.

Powrót do net/if.h: struct ifreq nawet nie istnieje po wstępnym przetworzeniu! W związku z tym skarga dotycząca wielkości magazynu.

Można złapać całą historię robiąc:

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

lub diff'ing ich w jakikolwiek inny sposób (np diff --side-by-side) zamiast vimdiff.

+0

Dzięki za wyjaśnienie. Właśnie natknąłem się na dokładnie ten sam problem. Czy istnieje sposób na pomyślne skompilowanie takiego kodu z '--std = c99'? – michas

+0

@michas Tak. Możesz zdefiniować '_BSD_SOURCE' lub' _SVID_SOURCE' [makro testowania funkcji] (http://www.gnu.org/software/libc/manual/html_node/Feature-Test-Macros.html) w swoich źródłach C. – ArjunShankar