2012-01-20 35 views
12

tôi đang làm một cái gì đó giống nhưSử dụng const tĩnh + const như mảng ràng buộc

Class.hpp này:

class Class { 

private: 
    static const unsigned int arraySize; 
    int ar[arraySize+2]; 
}; 

Class.cpp:

#include <Class.hpp> 
const unsigned int arraySize = 384; 

Trình biên dịch (q ++, một Trình biên dịch C++ cho hệ điều hành QNX dựa trên g ++) cung cấp cho tôi error: array bound is not an integer constant trong khi biên soạn một đơn vị bao gồm Class.hpp (không phải khi biên dịch Class.cpp).

Tại sao tính năng này không hoạt động? Tôi biết rằng một thành viên const tĩnh có thể được sử dụng như một mảng bị ràng buộc, được đảm bảo bởi tiêu chuẩn C++ (xem this anwser). Nhưng tại sao trình biên dịch không thấy kết quả của static const + const như một hằng số?

+1

Biên dịch tốt cho tôi (gcc 4.6.1), như thường lệ. Có lẽ là một lỗi trong trình biên dịch đó? –

+0

Tôi đã cập nhật ví dụ của mình để phù hợp hơn với mã thực của tôi. Có thể có vấn đề với việc khai báo về mảngSizeSize? – MBober

+1

Vui lòng xem tại đây: [DR # 721] (http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#721). Nó luôn luôn được dự định (và trong C++ 11 rõ ràng là trường hợp) mà initializer cho hằng số sẽ được hiển thị tại điểm mà thành viên dữ liệu tĩnh hoặc biến cố định được sử dụng để nó đủ điều kiện như là một biểu thức liên tục. –

Trả lời

12

Đây là mã tốt mà lẽ ra phải được chấp nhận bởi trình biên dịch:

class Class { 
    const static int arraySize = 384; 
    int ar[arraySize+2]; 
}; 

và nếu nó không phải là, trình biên dịch của bạn bị hỏng.

Tuy nhiên, nếu bạn di chuyển hằng số thực ra khỏi tệp tiêu đề sang đơn vị dịch đã chọn, điều đó sẽ làm mất hiệu lực mã.

// Class.h 
class Class { 
    const static int arraySize; 
    int ar[arraySize+2]; // ERROR 
}; 

// Class.cpp 
const int Class::arraySize = 384; 

Điều này là do kích thước của đối tượng Class không thể được xác định tại thời điểm biên dịch từ dữ liệu có sẵn trong tiêu đề. Đây không phải là chính xác là lý do đúng, nhưng lý do dọc theo những dòng này giúp hiểu các lỗi biên dịch như thế này.

Để tránh mắc các sai lầm như vậy, bạn có thể thay thế static const int bằng enum, ví dụ:

class Class { 
    enum { arraySize = 384 }; 
    int ar[arraySize+2]; 
}; 
+0

Cảm ơn bạn đã giải quyết. Tôi biết điều đó. Nhưng điều quan trọng là tôi phải kiểm tra xem đây có phải là mã C++ hợp lệ hay không. Nếu bạn nói đúng, thì chúng tôi có thể điền đơn khiếu nại chống lại công ty bán cho chúng tôi trình biên dịch. – MBober

+0

Ồ, bạn đã thay đổi mã trong câu hỏi của mình. Di chuyển liên tục ra khỏi tiêu đề thay đổi mọi thứ hoàn toàn. Tôi sẽ cập nhật câu trả lời của mình để tránh gây hiểu nhầm cho người khác. – bronekk

+0

Cảm ơn. Xin lỗi vì sự nhầm lẫn. – MBober

2

Tôi ngạc nhiên điều này thực sự biên dịch trên gcc, như một nhận xét cho biết. Vì số 384 không có trong tệp tiêu đề, kích thước của Class không được biết đến với các đơn vị biên dịch khác. Nó có thể không quan trọng ở một số đơn vị biên dịch tùy thuộc vào cách/nếu họ đang sử dụng Class, nhưng tôi không thể tưởng tượng biên dịch này:

// this is a source file called, say, blah.cpp 
#include <Class.hpp> 

void someFunc() 
{ 
    void *mem = malloc(sizeof(Class)); // size is not known, so this can't compile 

    // do something with mem 
} 

Bạn cần có trong .hpp của bạn:

class Class { 

private: 
    static const unsigned int arraySize = 384; 
    int ar[arraySize+2]; 
}; 

.. vì nó là trong OP mà bạn liên kết đến here.

+0

OP thay đổi câu hỏi. Ban đầu, hằng số được xác định trong tiêu đề. – avakar

+0

Nhận xét đề cập đến phiên bản trước của mã ví dụ trong câu hỏi của tôi. Tuy nhiên, nếu tôi định nghĩa const tĩnh của tôi trực tiếp trong header, nó sẽ biên dịch tốt. Vì vậy, bạn có thể chỉnh sửa câu trả lời của bạn và tôi sẽ chấp nhận nó. :) – MBober

+0

MBober bạn chỉ có thể chấp nhận một câu trả lời. – CashCow

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