Cấu trúc bạn đang trả về không phải là cấu trúc ẩn danh. C tiêu chuẩn định nghĩa một cấu trúc ẩn danh như là một thành viên của cấu trúc khác mà không sử dụng thẻ. Những gì bạn đang quay trở lại là một cấu trúc không có thẻ, nhưng vì nó không phải là một thành viên, nó không phải là vô danh. Gcc sử dụng tên < ẩn danh> để biểu thị cấu trúc không có thẻ.
Giả sử bạn cố gắng khai báo cấu trúc giống hệt nhau trong hàm.
struct { int x, y; } foo(void)
{
return (struct { int x, y; }){ 0 } ;
}
gcc phàn nàn về nó: loại không tương thích khi trở về gõ 'struct < nặc danh>' nhưng 'struct < nặc danh>' đã được dự kiến
Rõ ràng các loại không tương thích. Nhìn vào tiêu chuẩn chúng ta thấy rằng:
6.2.7 loại tương thích và loại composit
1: Có hai loại có loại tương thích nếu loại của họ đều giống nhau. Các quy tắc bổ sung để xác định xem hai loại có tương thích được mô tả trong 6.7.2 đối với các loại thông số, trong 6.7.3 đối với các loại định tính và trong 6.7.6 đối với người khai báo hay không. Ngoài ra, hai loại cấu trúc, công đoàn hoặc liệt kê được dịch riêng biệt đơn vị tương thích nếu thẻ và thành viên của chúng thỏa mãn các yêu cầu sau: Nếu thẻ được khai báo bằng thẻ, thẻ còn lại sẽ được khai báo với cùng một thẻ.Nếu cả hai được hoàn thành ở bất kỳ đâu trong đơn vị dịch tương ứng, thì các yêu cầu bổ sung sau đây áp dụng: sẽ có sự tương ứng một-một giữa các thành viên sao cho mỗi cặp thành viên tương ứng được khai báo với các loại tương thích; nếu một thành viên của cặp được khai báo với một bộ định danh căn chỉnh thì phần tử kia được khai báo với một bộ định tuyến căn chỉnh tương đương; và nếu một thành viên của cặp được khai báo với một tên, người kia được khai báo có cùng tên. Đối với hai cấu trúc, các thành viên tương ứng sẽ được khai báo theo cùng thứ tự. Đối với hai cấu trúc hoặc công đoàn, các trường bit tương ứng phải có cùng độ rộng. Đối với hai điều tra, các thành viên tương ứng sẽ có cùng giá trị.
Phần in đậm thứ hai, giải thích rằng nếu cả hai cấu trúc không có thẻ, chẳng hạn như trong ví dụ này, chúng phải tuân thủ các yêu cầu bổ sung được liệt kê sau phần đó. Nhưng nếu bạn nhận thấy phần in đậm đầu tiên, chúng phải nằm trong các đơn vị dịch riêng biệt, các cấu trúc trong ví dụ không phải là. Vì vậy, chúng không tương thích và mã không hợp lệ.
Nó là không thể làm cho mã chính xác vì nếu bạn khai báo một cấu trúc và sử dụng nó trong chức năng này, bạn phải sử dụng một thẻ, vi phạm các quy tắc mà cả hai đều có cấu trúc phải có thẻ giống nhau:
struct t { int x, y; } ;
struct { int x, y; } foo(void)
{
struct t var = { 0 } ;
return var ;
}
Again gcc phàn nàn: loại không tương thích khi trở về gõ 'struct t' nhưng 'struct < nặc danh>' đã được dự kiến
Có vẻ như nó một số hack của gcc.With C99 nghiêm ngặt nó được đưa ra lỗi http://ideone.com/665vM2 – Ankur
@Shan: Cú pháp định nghĩa hàm vẫn hợp pháp. Nó chỉ đơn thuần than phiền về câu lệnh trả về còn thiếu (và câu hỏi của tôi hỏi cách thực hiện một câu lệnh trả về đúng trong tình huống này). – Askaga
Không có thứ gì như cấu trúc ẩn danh trong C99. Bạn có thể tạo _ literound literals_ nhưng chúng luôn có phạm vi cục bộ. – Lundin