Ngoài câu trả lời được cung cấp bởi 2501 và nhận xét của bạn về "Trong trường hợp của tôi, thậm chí không có tờ khai chuyển tiếp", như sau.
Bất kỳ sử dụng mã số struct tag
nào được tính là (chuyển tiếp) khai báo kiểu cấu trúc, nếu nó chưa được khai báo trước đó. Mặc dù một cách chính thức hơn có thể nói rằng điều này đơn giản được tính là một loại, vì tiêu chuẩn C không đề cập đến "các khai báo chuyển tiếp của các loại cấu trúc", chỉ cần hoàn thành và incomplete structure types (6.2.5p22).
6.7.2 Type specifiers cho chúng ta biết một struct-hoặc-đoàn-specifier là một type-specifier, và 6.7.2.1 Structure and union specifiers paragraph 1 cho chúng ta biết rằng lần lượt structđịnh danh là một struct-hoặc-đoàn -specifier.
Giả sử bạn có một tuyên bố danh sách liên kết, một cái gì đó giống như
struct node {
struct node *next;
int element;
};
sau đó là "tuyên bố mong ngầm" của loại không đầy đủ này là điều cần thiết cho cấu trúc này để làm việc. Sau cùng, loại struct node
is only complete tại dấu chấm phẩy chấm dứt. Nhưng bạn cần phải tham khảo nó để khai báo con trỏ next
.
Ngoài ra, tuyên bố struct node
(loại không đầy đủ) có thể nằm ngoài phạm vi, giống như bất kỳ tuyên bố nào khác. Điều này xảy ra ví dụ nếu bạn có một số nguyên mẫu
int function(struct unknown *parameter);
nơi struct unknown
đi ra khỏi phạm vi ngay ở phần cuối của việc kê khai. Bất kỳ khai báo tiếp theo nào thì struct unknown
s thì không giống như cái này.Điều đó được hàm ý trong văn bản của 6.2.5p22:
Cấu trúc hoặc loại liên kết không rõ nội dung (như được mô tả trong 6.7.2.3) là loại không đầy đủ. Nó được hoàn thành, cho tất cả các tờ khai đó loại, bằng cách tuyên bố cấu trúc tương tự hoặc thẻ công đoàn với nó xác định nội dung sau trong cùng một phạm vi.
Đó là lý do tại sao gcc cảnh báo về vấn đề này:
foo.c:1:21: warning: 'struct unknown' declared inside parameter list
foo.c:1:21: warning: its scope is only this definition or declaration, which is probably not what you want
Bạn có thể khắc phục điều này bằng cách đặt một tờ khai chuyển tiếp thêm trước đó, mà làm cho phạm vi bắt đầu sớm hơn (và do đó kết thúc sau):
struct unknown;
int function(struct unknown *parameter);
Tôi không biết nhưng có lẽ vì trong khi ở giữa tuyên bố 'struct anything' bạn cần để có thể sử dụng 'struct anything', và có thể trình biên dịch sẽ không xử lý tất cả điều đó và chỉ cần đối xử với nó như hiện ? – Eregrith