2011-02-04 26 views
16

Tôi đang cố gắng biên dịch chương trình C trên hệ thống Linux. Tôi có một tuyên bố #include cho stdlib.h.Can -std = c99 có ngăn chặn #includes của tôi hoạt động bình thường không?

Khi tôi biên dịch chương trình với gcc như sau:

gcc -std=c99 -g -o progfoo progfoo.c progbar.c 

tôi nhận được cảnh báo về Implicit declaration of function [srand48, drand48, bzero, or close].

Biên soạn thay vì như:

gcc -g -o progfoo progfoo.c progbar.c 

không cho tôi những lời cảnh báo, nhưng nó la lên về việc sử dụng của tôi for vòng (đó là lý do cho việc thêm -std=c99 ở nơi đầu tiên).

Cho rằng man srand48 đề cập bao gồm <stdlib.h>, tôi có, tôi không chắc chắn vấn đề khác có thể là gì. Các vòng for không cần thiết cho bất kỳ thứ gì (chúng chỉ tiết kiệm thời gian khi khởi tạo mảng) vì vậy tôi không có vấn đề gì trong việc loại bỏ chúng, nhưng trước khi tôi muốn xác nhận xem tiêu chuẩn c99 có thay thế một số khía cạnh của #include của tôi hay không các câu lệnh.

Tôi đang sử dụng gcc 4.1.2-50 (Red Hat).

Trả lời

12

Can -std = c99 có ngăn chặn #includes của tôi hoạt động bình thường không?

Không, nhưng họ có thể xuất hiện những hạn chế trong kiến ​​thức của bạn về cách họ làm việc :-)


Trong khi các chức năng [sd]rand48 có một nguyên mẫu trong stdlib.h, họ đang ở trong một #ifdef, ít nhất trên hệ thống của tôi:

#if defined __USE_SVID || defined __USE_XOPEN 

Vì vậy, bạn có thể phải đặt rõ ràng một trong các macro đó.

Tuy nhiên, trước khi bạn thử, hãy lưu ý rằng nó không hoạt động. Đó là bởi vì tất cả những thứ này được kiểm soát với feature test macros của gcc.

Có một bộ quy tắc rất phức tạp được sử dụng để đặt hoặc tắt các tính năng cụ thể trong features.h và các macro được tạo ở đó kiểm soát những tệp tiêu đề bao gồm và loại trừ. Biến thể __USE_* bị xóa và được đặt trong tệp tiêu đề đó dựa trên các macro khác do chính bạn cung cấp.

Ví dụ: để có được __USE_SVID được đặt để bạn có thể sử dụng srand48, bạn cần cung cấp trình biên dịch với tham số -D_SVID_SOURCE.

Nhưng có lẽ cách dễ dàng hơn là chỉ sử dụng C99 với phần mở rộng GNU. Để làm điều đó, hãy thay thế -std=c99 bằng -std=gnu99.

Và, đối với bzeroclose, chúng có thể được lấy từ số strings.hunistd.h tương ứng.

tôi là một chút nhầm lẫn lúc đầu là tại sao các biên dịch với -std=c99 khi họ đã hoàn toàn không có gì để làm với C99 nhưng sau đó tôi nhận ra rằng lá cờ chỉ kiểm soát những gì tiêu đề tiêu chuẩn C cung cấp cho bạn.

Cả strings.h (lưu ý tên số nhiều, đây là khôngstring.h) cũng không unistd.h là một phần của tiêu chuẩn ISO C.

+2

+1, nhưng thực ra chúng là macro, chứ không phải biến. –

+0

Điểm tốt, @Matteo, tôi có xu hướng nghĩ về _macros_ như những thứ mà _do_ thứ, như '#define halfOf (x) ((x)/2)', trái với chỉ "cờ" để điều khiển biên dịch. Nhưng bạn là chính xác và việc sử dụng "biến" công việc của bản thân mình là apt để dẫn đến nhầm lẫn với các biến thực. Vì vậy, tôi đã thay đổi nó theo đề xuất của bạn. – paxdiablo

+2

Phải. Nó có thể hữu ích khi biết rằng khi bạn biên dịch không có '-std =' flag, bạn đang yêu cầu '-std = gnu89', là C89 cộng với phần mở rộng GNU - vì vậy C99 tương đương với chế độ này là' -std = gnu99 '. – caf

6

Có vẻ như các chức năng bạn đang sử dụng không phải là ISO C99, vì vậy khi bạn yêu cầu tuân thủ nghiêm ngặt C99, chúng sẽ không hiển thị.

Thông tin ở đây: https://bugzilla.redhat.com/show_bug.cgi?id=130815

Cờ -D_POSIX_C_SOURCE=200809L nên làm việc.

cũng Xem câu hỏi này: Why can't gcc find the random() interface when -std=c99 is set?

+2

Cũng giống như tôi phải tạo mẫu thử nghiệm chức năng cho "printf" trong HelloWorld.c? Tôi không nghĩ rằng bạn khá hiểu vấn đề của tôi. –

+0

Anh ta nhận được cảnh báo về hệ thống bao gồm các tệp (stdlib.h) nếu tôi hiểu đúng, không phải trong mã của riêng anh ấy. – Earlz

+0

Xin lỗi, không nhận ra những chức năng đó không tự viết bởi vì tôi chỉ viết mã C99 và chưa bao giờ sử dụng chúng. Đã chỉnh sửa câu trả lời của tôi. – Kevin

1

tờ khai Implicit (nơi một chức năng chưa được khai báo được giả định trở int) không còn được phép ở C99.

Điều đó nói rằng, gcc sẽ không hủy bỏ quá trình biên dịch.

Cố gắng bao gồm strings.h cho bzero, xem thêm câu trả lời của paxdiablo.

+0

Tôi nghĩ rằng đây là những gì đang xảy ra: không có gì thực sự * khác nhau *, nhưng các định nghĩa hàm ngầm định không được báo cáo mà không có tiêu chuẩn của c99. Điều này có nghĩa là #includes của tôi không hoạt động vì bất kỳ lý do gì. Địa ngục ... –

3

Các lỗi mà bạn đang nhận được làm cho nó âm thanh như các chức năng bạn đang sử dụng không phải là được tuyên bố. Bạn có chắc chắn bạn đang đưa các tiêu đề chính xác cho họ không?

Ngoài ra, sử dụng -std=c99 có thể vô hiệu hóa một số tiện ích mở rộng không nằm trong tiêu chuẩn. Không có hàm nào bạn đề cập là một phần của tiêu chuẩn C. Nếu bạn không thể tìm thấy các tiêu đề riêng biệt cho chúng, bạn có thể thử -std=gnu99.

2

-std=c99 làm cho tiêu đề bỏ qua bất kỳ thứ gì có thể xung đột với việc sử dụng tên ngoài không gian tên dành riêng C99, bao gồm tất cả các chức năng POSIX tiêu chuẩn. Cách di động để yêu cầu các tiêu đề cung cấp cho bạn các giao diện POSIX là xác định _POSIX_C_SOURCE thành một giá trị tương ứng với phiên bản POSIX mong muốn. Đối với POSIX mới nhất (2008), điều này có nghĩa là:

#define _POSIX_C_SOURCE 200809L 

hoặc trên dòng lệnh:

-D_POSIX_C_SOURCE=200809L 

Edit: Có vẻ như các chức năng bạn muốn không nằm trong cơ sở POSIX nhưng trong Tùy chọn XSI, vì vậy bạn nên xác định _XOPEN_SOURCE thành giá trị thích hợp (700 là giá trị mới nhất) để nhận chúng. Điều này cũng có thể được thực hiện từ dòng lệnh hoặc các tệp nguồn của bạn (nhưng nếu từ tệp nguồn, nó phải được thực hiện trước bao gồm bất kỳ tiêu đề hệ thống nào.

1

Bạn đang yêu cầu tuân thủ tiêu chuẩn và C99 không xác định srand48() làm chức năng được cung cấp bởi <stdlib.h>.

Đối với thư viện GNU C, bạn có thể yêu cầu tính năng bổ sung bằng cách định nghĩa một hoặc nhiều các tùy chọn được liệt kê trong các bình luận ở phía trên cùng của /usr/include/features.h, hoặc bằng cách #define trước khi bạn #include, hoặc với -D cờ để gcc.

Đối srand48() (và drand48()), bạn có thể muốn một trong hai -D_XOPEN_SOURCE=500 hoặc -D_SVID_SOURCE (hoặc #define _XOPEN_SOURCE 500 vv trong các tập tin nguồn).

bzero()close() nên làm việc ngay cả với -std=c99 nếu bạn #include các tập tin tiêu đề tài liệu cho họ, đó là <strings.h><unistd.h> tương ứng.

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