2015-06-03 19 views
9

Chức năng gets() đã bị xóa khỏi ngôn ngữ C. Không có chức năng như vậy tồn tại trong tiêu chuẩn.Tại sao tôi có thể sử dụng hàm gets() trong gcc -std = c11?

Tuy nhiên, tôi biên dịch đoạn mã sau:

#include <stdio.h> 

int main (void) 
{ 
    (void) gets (NULL); 
} 

sử dụng

gcc -std=c11 -pedantic-errors -Wall -Wextra 

và nó biên dịch mà không đưa ra bất kỳ lỗi hoặc cảnh báo. Tương tự,

#include <stdio.h> 

int gets; 

int main (void) 
{} 

sẽ không biên dịch (lỗi: 'được' redeclared làm loại biểu tượng khác).

Trong tiêu chuẩn 4. Sự phù hợp §6 chúng ta có thể đọc:

A conforming implementation may have extensions (including additional library functions), provided they do not alter the behavior of any strictly conforming program

Với trên, chúng tôi không nghĩ rằng gcc là tiêu chuẩn tuân thủ, ngay cả trong chế độ pedantic. Có một lý do cho điều này? Đây có phải là chủ ý hay là một lỗi?

Phiên bản GCC 4.9.1.

Edit:

gcc --version 
gcc (x86_64-win32-seh-rev1, Built by MinGW-W64 project) 4.9.1 
+1

GCC 4.8.2 ở đây. Trong chế độ pedantic đoạn đầu tiên sẽ không biên dịch bởi vì '' không bao giờ được định nghĩa. Trong chế độ không theo nghĩa đen, tôi nhận được 'cảnh báo: hàm \ 'gets' rất nguy hiểm và không nên được sử dụng.'. Đoạn thứ hai không phải là một vấn đề, bởi vì không có gì ngăn cản bạn tuyên bố một biểu tượng được gọi là 'được'. Ví dụ, 'int printf;' là hoàn toàn hợp pháp. Tôi có thiếu điểm của câu hỏi không? –

+1

Bạn đang sử dụng 'libc' nào? Trong các hệ thống giống như chuẩn của hệ thống Unix, thư viện C được vận chuyển với hệ điều hành. Ví dụ, trong Linux nó thường là _glibc_, đã bị xóa 'get' trong phiên bản 2.16 – myaut

+1

@StefanoSanfilippo Bạn dường như thiếu điểm liên quan đến nửa thứ hai, nó không nên thất bại (' được' không nên va chạm với bất cứ điều gì) nhưng nó có. – unwind

Trả lời

8

gcc chỉ là trình biên dịch chứ không phải toàn bộ quá trình triển khai.

Trên hệ thống của tôi (Linux Mint 17.3, gcc 4.8.4, GNU libc 2.19), tôi nhận được:

$ gcc -std=c11 -pedantic-errors -Wall -Wextra -c c.c 
c.c: In function ‘main’: 
c.c:5:3: error: implicit declaration of function ‘gets’ [-Wimplicit-function-declaration] 
    (void) gets (NULL); 
^

Để chẩn đoán chính xác lỗi, việc thực hiện cần phải phù hợp. Điều đó có nghĩa là cả trình biên dịch (không bao giờ cung cấp gets ở nơi đầu tiên) và thư viện.

Bạn đang sử dụng thư viện vẫn cung cấp chức năng gets. Do đó, việc triển khai thực hiện nói chung (bao gồm gcc trình biên dịch, thư viện và một vài phần khác) không phù hợp với C11.

Tóm lại: Đây không phải là vấn đề về gcc và không có nhiều điều mà gcc có thể thực hiện. (Vâng, nó thể ra-trường hợp đặc biệt chẩn đoán cho gets, nhưng sau đó nó sẽ phải xác định rằng nó không phải là một cuộc gọi hợp lệ để một hàm người dùng định nghĩa có cùng tên.)

+0

Mặc dù thư viện tiêu chuẩn C đã thả 'thư', thư viện GNU C vẫn bao gồm hàm này. – haccks

+2

Sao chép phản hồi của tôi về nhận xét khác của bạn: @haccks: Có và không. Trong tiêu đề do thư viện GNU C cung cấp, vẫn được khai báo, nhưng khai báo được bao quanh bởi #if! Được định nghĩa __USE_ISOC1 ... #endif. Việc triển khai vẫn còn đó, nhưng theo cách cho phép mã người dùng xác định một hàm có cùng tên. –

+0

OK. Bạn có coi đây là lỗi không? – haccks

1

Điểm mấu chốt của mã của bạn là:

#include <stdio.h> 

Bạn có cập nhật thư viện C hệ thống của bạn và các tiêu đề? Chúng cũng là một phần của việc triển khai C, cùng với trình biên dịch.

+0

Tôi đã chạy 'mingw-get update' và' mingw-get upgrade', cùng một lỗi sau đó. – Lundin

+0

Như Andrew đã đề cập, dòng chính là #include . Bạn nên tìm và phân tích tệp stdio.h được sử dụng bởi gcc để thực hiện việc biên dịch. Tệp đó có lẽ vẫn có hàm được định nghĩa. – Valy

1

cập nhật điều này có thể không phải là câu trả lời cho câu hỏi, tôi cố gắng làm cho nó mang tính thông tin.

Tôi tình cờ thấy rằng gcc được đề cập bị không tuân thủ tiêu chuẩn C11 đối với một số vấn đề thư viện glibc 2.16.

Xem gcc hỗ trợ tình trạng của C11: https://gcc.gnu.org/wiki/C11Status croped from the above link

Nhưng tôi không thể tìm ra định nghĩa về "vấn đề thư viện" và tình trạng hiện tại cho các phiên bản khác của glibc.

Vì vậy, tôi đã cố gắng trên ubuntu16.04 máy của tôi với phiên bản gcc 5.3.1 20160413, glibc phiên bản Ubuntu GLIBC 2.23 Chúng tôi có thể nhận được đủ cảnh báo về thời gian biên dịch, nhưng nó vẫn còn OK để thực thi các đối tượng tập tin đầu ra cho "tương thích ngược".

warning: implicit declaration of function ‘gets’ [-Wimplicit-function-declaration] 
warning: the `gets' function is dangerous and should not be used. 
+3

Điều này gây hiểu lầm. gcc đã không xóa 'get' vì gcc chưa bao giờ cung cấp' được' ở vị trí đầu tiên. Nó được cung cấp bởi thư viện, không phải bởi trình biên dịch (đó là lý do tại sao trang trạng thái đó đề cập đến nó như là một "vấn đề thư viện"). –

+0

@Keith Thompson. Cảm ơn câu trả lời! Điều đó thật tuyệt vời và hữu ích :). – TJC

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