Il codice seguente mostra un comportamento di gcc 4.6.2 di cui non posso tenere conto. La prima funzione dichiara una matrice statica di tipo vec_t, dove vec_t è un alias typedef per char non firmato. La seconda funzione è identica, tranne per il fatto che il tipo di vect_t è un parametro del modello. La seconda funzione non riesce a compilare con l'errore "diagnostico": la dimensione di archiviazione di "bitVec" non è costante ".Errore del compilatore? g ++ consente matrici statiche di dimensioni variabili, a meno che la funzione non sia basata su modelli.
#include <limits>
void bitvec_func()
{
const std::size_t nbits = 1e7;
typedef unsigned char vec_t;
const std::size_t WLEN = std::numeric_limits<vec_t>::digits;
const std::size_t VSIZ = nbits/WLEN+1;
static vec_t bitVec[nbits/VSIZ]; // Compiles fine
}
template <typename T>
void bitvec_func()
{
const std::size_t nbits = 1e7;
typedef T vec_t;
const std::size_t WLEN = std::numeric_limits<vec_t>::digits;
const std::size_t VSIZ = nbits/WLEN+1;
static vec_t bitVec[nbits/VSIZ]; // "error: storage size of ‘bitVec’ isn’t constant"
}
void flarf()
{
bitvec_func();
bitvec_func<unsigned char>();
}
Mi sembra che istanziare il modello con l'argomento < unsigned char> dovrebbe causare il compilatore di generare lo stesso codice come la prima funzione. Qualcuno può offrire qualche idea sul perché questo non sembra essere il caso?
[Addendum: la seconda funzione sarà compilare con "-std = C++ 0x" o "-std = gnu ++ 0x", ma mi piace ancora di capire come/se è sbagliato sotto il definizioni lingua precedenti]
ETA:.
la seconda funzione di compilazione se l'inizializzatore per nbits è cambiato:
const std::size_t nbits = 1e7; // Error
const std::size_t nbits = (std::size_t)1e7; // Okay
const std::size_t nbits = 10000000.0; // Error
const std::size_t nbits = 10000000; // Okay
In altre parole, sembra che se nbits
viene inizializzato con un'espressione di un integrale digitare, quindi nbits
viene considerato come un costante nella definizione di bitVec
. Se nbits
viene invece inizializzato con un'espressione a virgola mobile, il compilatore non lo vede più come costante nell'espressione per la dimensione di bitVec
e la compilazione non riesce.
Sono molto meno comodo chiamare "bug del compilatore" in C++ di quanto sarebbe in C, ma non riesco a pensare ad alcun'altra ragione per cui i suddetti 4 casi non sarebbero semanticamente identici. Qualcun altro si preoccupa di opina?
Potresti pubblicare il codice esatto che ti dà un errore del compilatore? Non riesco a riprodurlo. –
Questo è il codice esatto sopra. Il compilatore è gcc 4.6.2 e le opzioni sono "-O0 -g3 -c". –
Su un vecchio gcc 4.3.4, questo codice [compilato bene] (http://ideone.com/65Cl7). –