2012-06-29 21 views
8

Với mã,g ++: mảng ràng buộc không phải là một hằng số nguyên

const double rotationStep = 0.001; 
const int N = 2*int(M_PI/rotationStep) + 3; 

static unsigned int counts[N]; 

g++ cung cấp cho các lỗi:

array bound is not an integer constant before »]« token

Tôi đang sử dụng phiên bản g++/gcc 4.6.1

Can ai cho tôi biết lý do tại sao g++ phàn nàn về biểu thức?

+0

Vui lòng, bạn có thể xóa mã thông báo 'tĩnh' ra khỏi mã của bạn và biên dịch lại không? – higuaro

+0

@ h3nr1x: Đó là hành vi được xác định thực hiện (khi biểu thức được đánh giá là). –

+0

sẽ không biên dịch nếu không có từ khóa tĩnh – user765269

Trả lời

7

Theo tiêu chuẩn ISO C++ năm 2003, đó không phải là biểu thức hằng số tách rời . Trích dẫn phần 5,19 của tiêu chuẩn:

An integral constant-expression can involve only literals (2.13), enumerators, const variables or static data members of integral or enumeration types initialized with constant expressions (8.5), non-type tem-plate parameters of integral or enumeration types, and sizeof expressions. Floating literals (2.13.3) can appear only if they are cast to integral or enumeration types.

Bạn có thể thay đổi điều này:

const double rotationStep = 0.001; 
const int N = 2*int(M_PI/rotationStep) + 3; 

này:

const int inverseRotationStep = 1000; 
const int N = 2*int(M_PI)*inverseRotationStep + 3; 

(Đó là giả định M_PI được định nghĩa ở đâu đó; nó không quy định trong tiêu chuẩn , nhưng nó là một phần mở rộng phổ biến.)

Tiêu chuẩn ISO C++ 2011 loo cảm nhận điều này một chút. 5.19p3 (trích dẫn dự thảo N3337) nói:

An integral constant expression is a literal constant expression of integral or unscoped enumeration type.

tôi nghĩ2*int(M_PI/rotationStep) + 3, và do đó N, đủ điều kiện theo quy định mới, nhưng nó có khả năng biên dịch của bạn vẫn chưa thực hiện chúng.

+0

+1 Câu trả lời hay hơn –

4

Vấn đề là ...

g++ gives: array bound is not an integer constant before »]« token 

Một giá trị const không phải là một biểu thức hằng số (mặc dù nó khá dễ hiểu tại sao điều này sẽ làm bạn bối rối).

EDIT: Tôi giả sử C khi lần đầu tiên tôi đọc nội dung này. Vấn đề ở đây là biểu hiện này không được đánh giá ở thời gian biên dịch:

const int N = 2*int(M_PI/rotationStep) + 3; 

Trong khi điều này sẽ

const int N = 10; 

Như @ildjarn lưu ý trong các ý kiến, nổi điểm số học không đảm bảo được đánh giá tại thời gian biên dịch. Here is a related SO post I found.

+0

-_- nhưng N được cố định tại thời gian biên dịch:/ Vì vậy, có một giải pháp khác để sử dụng #define? – user765269

+0

Nếu GCC có hỗ trợ cho nó, bạn có thể sử dụng constexpr ... – MFH

+0

@ user765269: Số học dấu chấm động không được đảm bảo sẽ được thực hiện tại thời gian biên dịch như số học tích phân là. – ildjarn

1

Như Ed đã được chỉ ra, tối ưu hóa các hoạt động điểm động, bao gồm cả việc gấp liên tục, không được đảm bảo xảy ra vào thời gian biên dịch. Intel's page về chủ đề đưa ra một vài ví dụ, nhưng chủ yếu là hành vi làm tròn có thể khác nhau và các hoạt động điểm nổi có thể ném ngoại lệ. This paper chuyên sâu hơn một chút (phần 8.3, "Giảm số học").

GCC không chỉ hỗ trợ

"floating-point expression contraction such as forming of fused multiply-add operations if the target has native support for them"

như đã đề cập trong mô tả cho cờ FFP-hợp đồng trong cuốn hướng dẫn compiler optimizations.

+0

* "** thời gian biên dịch ** các hoạt động điểm động không được đảm bảo ** xảy ra tại thời gian biên dịch **." * - Không thể nhận được nhiều hơn nữa khó hiểu hơn thế! : D –

+0

Ồ, vâng. Cố định (tôi nghĩ). Cảm ơn bạn :) – niko

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