2013-03-26 11 views
6

Tôi đang sử dụng mặc định C trong gcc.C khởi tạo cấu trúc const thành viên với biến const hiện tại

Mã của tôi:

typedef struct _OpcodeEntry OpcodeEntry; 

//

struct _OpcodeEntry 
{ 
    unsigned char uOpcode; 
    OpcodeMetadata pMetadata; 
}; 

//

const OpcodeMetadata omCopyBytes1 = { 1, 1, 0, 0, 0, 0, &CopyBytes }; 

const OpcodeEntry pOpcodeTable[] = 
{ 
    { 0x0, omCopyBytes1 }, 
}; 

Lỗi:

error: initializer element is not constant 
error: (near initialization for 'pOpcodeTable[0].pMetadata') 

Nếu tôi thay đổi omCopyBytes1 thành những gì nó thực sự được đặt trong dòng trên, thì mã sẽ biên dịch tốt. Tôi đang làm gì sai?

Trả lời

5

Bạn không thể sử dụng omCopyBytes1 để khởi tạo thành viên của mảng pOpcodeTable[], vì omCopyBytes1 là biến là hằng số thời gian chạy, không phải là hằng số biên dịch. Trình khởi tạo tổng hợp trong C phải là hằng số biên dịch thời gian, đó là lý do tại sao mã từ bài đăng của bạn không biên dịch.

Là một biến, omCopyBytes1 có vị trí riêng trong bộ nhớ, được khởi tạo thành một mảng các mục. Bạn có thể sử dụng biến đó bằng một con trỏ, như thế này:

struct _OpcodeEntry { 
    unsigned char uOpcode; 
    const OpcodeMetadata *pMetadata; 
}; 
... 
const OpcodeEntry pOpcodeTable[] = { 
    { 0x0, &omCopyBytes1 }, // This should work 
}; 

Ngoài ra, bạn có thể làm cho nó một hằng số tiền xử lý:

#define omCopyBytes1 { 1, 1, 0, 0, 0, 0, &CopyBytes } 

Nếu định nghĩa theo cách này, các omCopyBytes1 sẽ không còn là một biến : nó sẽ là một định nghĩa tiền xử lý biến mất trước khi trình biên dịch được thực hiện. Tôi sẽ khuyên bạn nên chống lại các phương pháp tiền xử lý, nhưng nó có trong trường hợp bạn phải làm điều đó.

+0

Các biểu thức liên tục có thực sự cần thiết để khởi tạo tất cả các tập hợp trong C99 không? Tôi không thấy bất cứ điều gì trong phần 6.7.8 của tiêu chuẩn C99 nói như vậy (khác với đối tượng của thời gian lưu trữ tĩnh). – jamesdlin

0

Trong C, trình khởi tạo cho các đối tượng có thời lượng lưu trữ tĩnh phải là biểu thức không đổi. Biến số const không phải là một biểu thức liên tục.

+0

Chắc chắn bạn không có nghĩa là * tất cả * initializers phải là biểu thức liên tục, trừ khi bạn đang tuyên bố rằng một cái gì đó như 'int x = rand(); 'là bất hợp pháp. – jamesdlin

+0

Cảm ơn .. Đã sửa lỗi. –