2012-06-29 19 views
8

con el código,g ++: array unida no es una constante entera

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

static unsigned int counts[N]; 

g++ da el error:

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

estoy usando g++/gcc versión 4.6.1

Can Alguien me diga por qué g++ se queja de la expresión?

+0

Por favor, ¿puedes borrar el símbolo 'static' de tu código y recompilarlo? – higuaro

+0

@ h3nr1x: Es un comportamiento definido por la implementación (cuando se evalúa la expresión). –

+0

no se compilará sin la palabra clave estática – user765269

Respuesta

7

A partir del estándar ISO C++ de 2003, esa no es una expresión de constante integral . Citando la sección 5.19 de la norma:

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.

puede cambiar este nombre:

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

a esto:

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

(Eso suponiendo M_PI se define en alguna parte; no se especifica en la norma , pero es una extensión común.)

El loo ISO 2011 estándar de ISO siente esto un poco. 5.19p3 (citando el proyecto N3337) dice:

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

Yo creo 2*int(M_PI/rotationStep) + 3, y por lo tanto N, califica bajo las nuevas reglas, pero es probable que su compilador todavía no ponerlas en práctica.

+0

+1 Mejor respuesta –

4

El problema es que ...

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

Un valor const no es una expresión constante (aunque es bastante comprensible por qué esto podría confundir).

EDITAR: Asumí C la primera vez que leí esto. El problema aquí es que esta expresión no se evalúa en tiempo de compilación:

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

Si bien esto sería

const int N = 10; 

Como @ildjarn señaló en los comentarios, flotante aritmética de punto no está garantizada para ser evaluados en tiempo de compilación Here is a related SO post I found.

+0

-_- pero N se arregló en tiempo de compilación:/ ¿Hay alguna otra solución para usar #define? – user765269

+0

Si GCC tiene soporte para esto, puede usar constexpr ... – MFH

+0

@ user765269: La aritmética de coma flotante no se garantiza para realizarse en tiempo de compilación como lo es la aritmética integral. – ildjarn

1

Como ya se señaló, las optimizaciones de operaciones de punto flotante, incluido el plegado constante, no están garantizadas en el momento de la compilación. Intel's page sobre el tema da algunos ejemplos, pero principalmente es que el comportamiento de redondeo puede ser diferente y que las operaciones de punto flotante pueden arrojar excepciones. This paper va un poco más en profundidad (sección 8.3, "Reducción aritmética").

solo soporta GCC

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

como se menciona en la descripción de la bandera FFP-contrato en el manual compiler optimizations.

+0

* "** en tiempo de compilación ** las operaciones de punto flotante no están garantizadas ** en el momento de la compilación **." * - No se puede obtener mucho más ¡confuso que eso! : D –

+0

Oh, sí. Solucionado (creo). Gracias :) – niko

Cuestiones relacionadas