2009-08-20 3 views
2

Может ли кто-нибудь объяснить (что может быть мое восприятие) несоответствие в ошибках в следующем коде? По сути, почему «// OK» в порядке и ошибки «// ошибки»?C++ Константные выражения и границы массива

(Компилятор i686-яблоко-darwin9-г ++ - 4.0.1 (GCC) 4.0.1 (Apple Inc. построить 5490))

#include <cmath> 
#include <iosfwd> 

template <typename T> 
class TT{ 
    char _c[sizeof(T) + static_cast<size_t>(::ceil(sizeof(T) * 0.001)) + 1]; // error: array bound is not an integer constant 
    //char _c[sizeof(T) + static_cast<size_t>(sizeof(T) * 0.001) + 1]; // OK 
    T _t; 
}; 

class IS{ 
    unsigned char* _u; 
    double _d; 
}; 

char s[static_cast<size_t>(::ceil(sizeof(TT<IS>) * 10.0))]; // error: array bound is not an integer constant 

int main(int argc, char** argv){ 
    char a[static_cast<size_t>(10.0)]; // OK 
    char b[static_cast<size_t>(::ceil(sizeof(double) * 10.0))]; // OK 

    TT<int> it; 
    char c[static_cast<size_t>(::ceil(sizeof(TT<int>) * 10.0))]; // OK 

    TT<IS> is; 
    char d[static_cast<size_t>(::ceil(sizeof(TT<IS>) * 10.0))]; // OK 

    return 0; 
} 

Как примечание стороны, я знаю C + + 0x: Обобщенное постоянное выражение.

ответ

5

Проблема заключается в том, где объявляются массивы.

Вы можете объявить массив с не постоянным размером на уровне файла, поскольку компилятору необходимо знать во время компиляции, сколько выделить, и в вашем случае для этого потребуется вызов функции.

Когда вы делаете то же самое на уровне функции, расширение C++, поддерживающее ваш компилятор (это не разрешено стандартом) - компилятор испускает код, который вызывается функцией, вычисляет значение и выделяет массив на стек в во время выполнения.

+0

Вот что я хотел проверить. В функции, которая имеет ceil() (или любую другую функцию в этом отношении) в объявлении массива, не нарушает семантики/правила языка. Но в классе, размер массива которого зависит от функции, будет разбит sizeof(). В этом случае sizeof (TT) недоступен во время компиляции. Большое спасибо! Цените свое время! – kvs

+0

Отличный ответ sharptooth. BTW, с компилятором Microsoft Visual C++, вы также не можете делать это на уровне функции. – Aamir

Смежные вопросы