9

With the code,

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

static unsigned int counts[N];

g++ gives the error:

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

I am using g++/gcc version 4.6.1

Can anybody tell me why g++ complains about the expression?

Jay Sullivan
  • 17,332
  • 11
  • 62
  • 86
user765269
  • 311
  • 1
  • 4
  • 12

3 Answers3

7

As of the ISO C++ standard of 2003, that's not an integral constant-expression. Quoting section 5.19 of the standard:

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.

You could change this:

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

to this:

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

(That's assuming M_PI is defined somewhere; it's not specified in the standard, but it's a common extension.)

The 2011 ISO C++ standard loosens this up a bit. 5.19p3 (quoting the N3337 draft) says:

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

I think 2*int(M_PI/rotationStep) + 3, and therefore N, qualifies under the new rules, but it's likely your compiler doesn't yet implement them.

Keith Thompson
  • 254,901
  • 44
  • 429
  • 631
4

The problem is that...

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

A const value is not a constant expression (though its quite understandable why this would confuse you).

EDIT: I assumed C when I first read this. The problem here is that this expression is not being evaluated at compile time:

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

While this would be

const int N = 10;

As @ildjarn noted in the comments, floating point arithmetic is not guaranteed to be evaluated at compile time. Here is a related SO post I found.

Community
  • 1
  • 1
Ed S.
  • 122,712
  • 22
  • 185
  • 265
  • -_- but N is fixed at compile time :/ So is there a another solution to using #define ? – user765269 Jun 29 '12 at 22:19
  • @user765269 : Floating-point arithmetic is not guaranteed to be performed at compile time like integral arithmetic is. – ildjarn Jun 29 '12 at 22:29
  • @user765269: I was actually thinking C when I read this (which has a more restrictive definition of what constitutes a constant expression), not C++. The problem is that the expression is *not* evaluated at compile time. – Ed S. Jun 29 '12 at 22:29
  • If you take out the `static` keyword it should compile without warnings – higuaro Jun 29 '12 at 22:35
  • @h3nr1x: it's implementation defined. For example, VS2010 still throws a hissy fit. – Ed S. Jun 29 '12 at 22:35
  • @h3nr1x: How so? C++ (unlike C starting with C99) doesn't have variable-length arrays -- though some compilers may support them as an extension. – Keith Thompson Jun 29 '12 at 22:38
  • @EdS. Do you mean that the `const` declaration with floating point is the implementation defined part or the use of the `static` keyword in the declaration? – higuaro Jun 29 '12 at 22:40
  • @h3nr1x: The floating point part, i.e., when the expression will be evaluated. – Ed S. Jun 29 '12 at 22:44
  • @KeithThompson I just copy/pasted the code, compiled it using `g++ test.cpp`, and then it throwed the same error message, after that, I deleted the `static` keyword, and the error message disappeared – higuaro Jun 29 '12 at 22:46
  • 1
    @h3nr1x: Try compiling with `g++ -pedantic`. I get "warning: ISO C++ forbids variable length array ‘counts’ [-Wvla]". (g++ is non-conforming by default.) – Keith Thompson Jun 29 '12 at 22:51
1

As Ed already pointed out, optimizations of floating point operations, including constant folding, are not guaranteed to happen at compile time. Intel's page on the subject gives a few examples, but mainly it's that the rounding behavior may be different and that floating point operations may throw exceptions. This paper goes a bit more in-depth (section 8.3, "Arithmetic Reduction").

GCC does only support

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

as mentioned in the description for the ffp-contract flag in the compiler optimizations manual.

niko
  • 1,816
  • 13
  • 13
  • *"**compile-time** floating point operations are not guaranteed to **happen at compile time**."* - Can't get much more confusing than that! :D – Ed S. Jun 29 '12 at 23:11