2012-01-20 4 views
12

я делаю что-то вроде этогоИспользование статического сопзЬ + сопзЬ, как массив, связанный

Class.hpp:

class Class { 

private: 
    static const unsigned int arraySize; 
    int ar[arraySize+2]; 
}; 

Class.cpp:

#include <Class.hpp> 
const unsigned int arraySize = 384; 

Компилятор (д ++, А C++ для ОС QNX на основе g ++) дает мне error: array bound is not an integer constant при компиляции единицы, включая Class.hpp (а не при компиляции Class.cpp).

Почему это не работает? Я знаю, что статический константный член может использоваться как привязка к массиву, гарантированный стандартом C++ (см. this anwser). Но почему компилятор не видит результат static const + const как константу?

+1

Компиляция отлично подходит для меня (gcc 4.6.1), как и должно быть. Вероятно, ошибка в том компиляторе? –

+0

Я обновил свой пример, чтобы лучше совместить мой реальный код. Может быть, есть проблема с форвардным объявлением arraySize? – MBober

+1

См. Здесь: [DR # 721] (http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#721). Это всегда было предназначено (и в C++ 11 явно указано), что инициализатор для константы должен быть видимым в точке, где элемент статических данных или константная переменная использовались для того, чтобы он квалифицировался как постоянное выражение. –

ответ

12

Это хороший код, который должен был быть принят компилятором:

class Class { 
    const static int arraySize = 384; 
    int ar[arraySize+2]; 
}; 

и если это не так, ваш компилятор не работает.

Однако, если вы перемещаете фактическую константу из файла заголовка в выбранную единицу перевода, это делает недействительным код.

// Class.h 
class Class { 
    const static int arraySize; 
    int ar[arraySize+2]; // ERROR 
}; 

// Class.cpp 
const int Class::arraySize = 384; 

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

Чтобы избежать таких ошибок, вы можете заменить static const int на enum, например.

class Class { 
    enum { arraySize = 384 }; 
    int ar[arraySize+2]; 
}; 
+0

Спасибо за обходной путь. Я знал это сам. Но для меня важно проверить, действительно ли это код на C++. Если вы правы, мы можем заполнить жалобу на компанию, которая продала нам компилятор. – MBober

+0

О, вы изменили код на свой вопрос. Постоянное перемещение от заголовка полностью меняет ситуацию. Я уточню свой ответ, чтобы не вводить в заблуждение других. – bronekk

+0

Спасибо. Извините за путаницу. – MBober

2

Я удивлен, что это действительно компилируется на gcc, как говорится в комментарии. Поскольку 384 не находится в файле заголовка, размер Class не известен другим единицам компиляции. Это не вопрос в некоторой единице компиляции в зависимости от того, как/если они используют Class, но я не могу представить себе эту компиляцию:

// this is a source file called, say, blah.cpp 
#include <Class.hpp> 

void someFunc() 
{ 
    void *mem = malloc(sizeof(Class)); // size is not known, so this can't compile 

    // do something with mem 
} 

Вы должны иметь в своем .hpp:

class Class { 

private: 
    static const unsigned int arraySize = 384; 
    int ar[arraySize+2]; 
}; 

.. как есть в OP, который вы ссылаетесь на here.

+0

OP изменить вопрос. Первоначально константа была определена в заголовке. – avakar

+0

Комментарии относятся к более ранней версии кода примера в моем вопросе. Однако, если я определяю свой статический const непосредственно в заголовке, он компилируется отлично. Поэтому вы можете отредактировать свой ответ, и я приму его. :) – MBober

+0

MBober вы можете принять только один ответ. – CashCow