2012-05-03 38 views
10

Đây là một số mã tôi đang soạn thảo trên Linux:Tại sao C99 phàn nàn về kích thước lưu trữ?

#include <net/if.h> 

int main() { 
    struct ifreq ifr; 
} 

gcc test.c là tốt.

gcc -std=gnu99 test.c là tốt.

gcc -std=c99 test.c không thành công với các lỗi sau:

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

gì khác biệt về C99 rằng nó không giống như định nghĩa của struct ifreq trong Linux?

+0

Tôi tin rằng câu hỏi của tôi trùng lặp với điều này: http://stackoverflow.com/questions/3875197/std-c99-wtf-on-linux –

Trả lời

16

Đó là một chuỗi các hậu quả của tiền xử lý và GNU C so với C99.

Đầu tiên, net/if.h:

  1. net/if.h bao gồm features.h
  2. Sau đó, nó định nghĩa struct ifreq bên trong một khối #ifdef __USE_MISC.

Vì vậy:

  1. __USE_MISC là gì? - nó là thứ phổ biến đối với BSD và Hệ thống V
  2. Nó có được xác định tại điểm này không? - Chúng ta cần phải kiểm tra xem trong features.h

Vì vậy, bây giờ, features.h:

  1. Khi bạn sử dụng --std=c99 GCC theo mặc định định nghĩa __STRICT_ANSI__ (vì điều đó là những gì C99)
  2. Trong khi tiền xử lý features.h, khi __STRICT_ANSI__ bật, các tính năng BSD và System V không khởi động. tức là __USE_MISC không được xác định.

Sao lưu đến net/if.h: struct ifreq thậm chí không tồn tại sau khi xử lý trước! Do đó, khiếu nại về kích thước lưu trữ.

Bạn có thể nắm bắt được toàn bộ câu chuyện bằng cách thực hiện:

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

hoặc diff'ing chúng trong bất kỳ cách nào khác (như diff --side-by-side) thay vì vimdiff.

+0

Cảm ơn bạn đã giải thích. Tôi chỉ vấp phải chính xác cùng một vấn đề. Có cách nào để biên dịch thành công mã như vậy với '--std = c99'? – michas

+0

@michas Có. Bạn có thể định nghĩa '_BSD_SOURCE' hoặc' _SVID_SOURCE' [macro thử nghiệm tính năng] (http://www.gnu.org/software/libc/manual/html_node/Feature-Test-Macros.html) trong các nguồn C của bạn. – ArjunShankar

Các vấn đề liên quan