2010-01-29 42 views
6

Tôi đang cố gắng hiểu hành vi chính xác của các bộ định danh lớp lưu trữ trong C99 và một số hành vi GCC dường như không tuân theo thông số kỹ thuật, trừ khi tôi hiểu sai thông số. Từ 6.2.2 (2):Liên kết trong C: GCC có tuân thủ thông số kỹ thuật C99 hay tôi không hiểu thông số kỹ thuật?

Trong một đơn vị dịch, mỗi tuyên bố của số nhận dạng với liên kết nội bộ biểu thị cùng một đối tượng hoặc chức năng.

Tuy nhiên, tôi đã thử nghiệm GCC (powerpc-apple-darwin9-gcc-4.2.1) với chương trình sau đây:

#include <stdio.h> 
static int f() { 
    static int x = 0; 
    return x++; 
} 
static int g() { 
    static int x = 0; 
    return x++; 
} 
int main(int argc, char *argv[]) { 
    printf("g() = %i\n", g()); 
    printf("g() = %i\n", g()); 
    printf("f() = %i\n", f()); 
    printf("f() = %i\n", f()); 
    return 0; 
} 

Biên soạn với -std=c99, It in như sau:

g() = 0 
g() = 1 
f() = 0 
f() = 1 

Nếu tôi hiểu thông số chính xác, cần in:

g() = 0 
g() = 1 
f() = 2 
f() = 3 

Tôi hiểu tại sao GCC sẽ đi chệch khỏi spec ở đây, tôi chỉ tự hỏi nếu có một lời giải thích sâu sắc hơn cho hành vi này.

Trả lời

9

Đoạn tiếp theo, 6.2.2/3, là rất quan trọng:

Nếu tuyên bố của một tập tin nhận dạng phạm vi cho một đối tượng hoặc một hàm chứa các lưu trữ lớp specifier tĩnh, nhận dạng có liên kết nội bộ.

(lưu ý số nhận dạng phạm vi tệp được nhấn mạnh).

Biến tĩnh của bạn x không có phạm vi tệp, chúng có phạm vi chặn.

+0

Nói cách khác, mỗi x là cục bộ cho hàm khai báo nó. –

+0

Cảm ơn. Thật dễ dàng để bỏ lỡ các từ trong spec. –

+2

@Dietrich: Đúng vậy. Trong thực tế, nó rất dễ dàng, tôi bỏ lỡ phần có liên quan và quan trọng hơn, mà sth đăng như là một câu trả lời. –

10

Trong 6.2.2 (6) nó nói:

Các định danh sau đây không có mối liên hệ: [...] một phạm vi khối định danh cho một đối tượng tuyên bố mà không cần sự xác định extern lưu trữ-class .

Biến tĩnh là số nhận dạng phạm vi khối cho đối tượng và không được khai báo extern. Do đó họ không có liên kết, đặc biệt là không liên kết nội bộ.

+2

+1; có liên quan nhiều hơn đoạn tôi đã trích dẫn. –

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