2012-01-20 18 views
12

robię coś takiegoKorzystanie static const + const jako tablica związany

Class.hpp:

class Class { 

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

Class.cpp:

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

kompilatora (q ++, A kompilator C++ dla systemu QNX na podstawie g ++) daje mi error: array bound is not an integer constant podczas kompilowania jednostki zawierającej Class.hpp (nie podczas kompilacji Class.cpp).

Dlaczego to nie działa? Wiem, że statyczny element const może być używany jako tablica powiązana, gwarantowana przez standard C++ (patrz this anwser). Ale dlaczego kompilator nie widzi wyniku jako stałej w postaci static const + const?

+1

Kompiluje się dobrze dla mnie (gcc 4.6.1), tak jak powinien. Prawdopodobnie błąd w tym kompilatorze? –

+0

Zaktualizowałem mój przykład, aby lepiej pasował do mojego prawdziwego kodu. Być może jest problem z deklaracją forward arraySize? – MBober

+1

Patrz tutaj: [DR # 721] (http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#721). Zawsze było to zamierzone (i w C++ 11 jest wyraźnie), że inicjator dla stałej powinien być widoczny w punkcie, w którym element danych statycznych lub stała stała została użyta do zakwalifikowania jako wyrażenie stałe. –

Odpowiedz

12

To dobry kod, który powinien zostały zaakceptowane przez kompilator:

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

a jeśli tak nie jest, kompilator jest zepsuty.

Jednakże, jeśli przeniesiesz aktualną stałą z pliku nagłówkowego do wybranej jednostki tłumaczeniowej, to unieważni kod.

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

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

To dlatego, że wielkość swojego obiektu Class nie może być ustalona w czasie kompilacji z danymi dostępnymi w sam cel. Nie jest to właściwy powód, ale rozumowanie w tym zakresie pomaga zrozumieć błędy kompilacji, takie jak to. Aby uniknąć takich błędów, można zamienić na:

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

Dziękujemy za obejście tego problemu. Sam to wiedziałem. Ale ważne jest dla mnie sprawdzenie, czy jest to poprawny kod C++. Jeśli masz rację, możemy wnieść skargę przeciwko firmie, która sprzedała nam kompilator. – MBober

+0

Och, zmieniłeś kod na swoje pytanie. Przesunięcie stałej od nagłówka całkowicie zmienia rzeczy. Zaktualizuję swoją odpowiedź, aby uniknąć wprowadzania w błąd innych. – bronekk

+0

Dzięki. Przepraszam za zamieszanie. – MBober

2

Jestem zaskoczony, że faktycznie kompiluje się na gcc, jak mówi komentarz. Ponieważ 384 nie znajduje się w pliku nagłówkowym, rozmiar Class nie jest znany innym jednostkom kompilacji. Może nie ma znaczenia w niektórych jednostek kompilacji zależności od tego jak/jeśli są one za pomocą Class, ale nie mogę sobie wyobrazić tej kompilacji:

// 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 
} 

trzeba mieć w swojej .hpp:

class Class { 

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

.. tak jak w OP, który łączysz z here.

+0

OP zmienić pytanie. Oryginalnie stała została zdefiniowana w nagłówku. – avakar

+0

Komentarze odnoszą się do wcześniejszej wersji przykładowego kodu w moim pytaniu. Jednak jeśli definiuję moją statyczną const bezpośrednio w nagłówku, kompiluje się ona dobrze. Możesz edytować swoją odpowiedź, a ja ją zaakceptuję. :) – MBober

+0

MBober można zaakceptować tylko jedną odpowiedź. – CashCow

Powiązane problemy