2013-08-10 53 views
8

tôi có một chương trình với một số chuỗi toàn cầu được xác định ở phía trên cùng của tập tin như thế này:C: Gán "static const char * const" thành "const tĩnh char *"

static const char * const STRING_A = "STRING A"; 
static const char * const STRING_B = "STRING B"; 

Sau đó, trong chương trình chính Tôi lặp lại nhiều lần gọi một hàm. Hàm này chứa một con trỏ trỏ đến các chuỗi ở trên, tùy thuộc vào đầu vào của người dùng. Theo mặc định tôi muốn nó được thiết lập để STRING_A, vì vậy những gì tôi về cơ bản có là thế này:

// Called repeatedly from a loop. 
void input_function() 
{ 
    static const char *current = STRING_A; 

    // Do stuff and reassign different strings to "current" 
    ... 
} 

Vấn đề mà tôi có là khi biên soạn tôi nhận được "lỗi: yếu tố khởi tạo phải là không đổi". Điều này đang sử dụng GCC 4.7.2. Điều làm tôi bối rối hơn là lỗi sẽ biến mất nếu tôi loại bỏ từ khóa "tĩnh" trong hàm đầu vào. Đây không phải là một giải pháp mặc dù, như là từ khóa tĩnh là cần thiết cho các chức năng để theo dõi chuỗi hiện tại giữa các cuộc gọi.

Rõ ràng là tôi có thể sửa lỗi này theo nhiều cách, đơn giản nhất chỉ bằng cách loại bỏ một số vòng loại const. Nhưng tôi muốn hiểu tại sao điều này không hiệu quả.

Sự hiểu biết hiện tại của tôi là các biến chuỗi chung không thể sửa đổi để trỏ đến các chuỗi khác nhau và không thể sửa đổi các ký tự riêng lẻ của chúng. Từ khóa tĩnh giữ chúng cục bộ với tệp nguồn.

Đối với biến số current trong hàm của tôi, từ khóa tĩnh cho phép nó giữ lại giá trị của nó qua nhiều cuộc gọi đến hàm, và vòng loại const trong trường hợp này có nghĩa là chuỗi được trỏ đến bởi current có thể thay đổi - nhưng không phải là các ký tự của chuỗi mà nó trỏ đến.

Tôi không thấy bất kỳ mâu thuẫn nào trong các câu lệnh đó, vì vậy tôi không hiểu tại sao trình biên dịch đưa ra lỗi - đặc biệt là tại sao nó không có vấn đề nếu chỉ định "tĩnh" của current bị xóa.

Cảm ơn nếu ai đó có thể giải thích vấn đề ở đây là gì.

Trả lời

7

6.7.8/4 [C99]:

All the expressions in an initializer for an object that has static storage duration shall be constant expressions or string literals.

STRING_A không phải là, vì thế mà lỗi.

Một đến cách để làm việc xung quanh đây sẽ là dọc theo dòng sau đây:

void input_function() 
{ 
    static const char *current = NULL; 
    if (current == NULL) { 
     current = STRING_A; 
    } 

    ... 
} 
+0

tôi vẫn quấn quanh đầu tôi nó nhưng nhờ cho câu trả lời nhanh. –

3

Đó là vì STRING_A không phải là một hằng số thời gian biên dịch. Tuy nhiên, cách diễn giải của bạn là đúng, bạn không thể khởi tạo hằng số thành giá trị không cố định (chẳng hạn như STRING_A).

Trình biên dịch biết những gì STRING_A điểm trong khi biên dịch? Nó không - STRING_A sẽ trỏ đến địa chỉ khác nhau trong phần chỉ đọc của bộ nhớ trên mỗi thực hiện chương trình, phụ thuộc vào nơi chuỗi ký tự trong bộ nhớ.

Bạn sẽ cần phải làm như sau để làm việc xung quanh sự kiềm chế này trong khi liên quan tác dụng tương tự:

// Defines current to be a null pointer. 
static const char *current = NULL; 

// Determine if current is a null pointer. 
if (current == NULL) current = STRING_A; 
+0

Cảm ơn câu trả lời nhanh chóng, tôi đã phải đưa nó cho NPE mặc dù bởi vì anh ấy bằng cách nào đó thậm chí còn nhanh hơn. Cảm ơn một lần nữa. –