2016-11-30 45 views
0

我得到當我按以下方式做了一個錯誤:我怎麼能解決這個錯誤:表達式必須有一個常數值。環境是VS 2013

首先,我在文件light.cpp聲明一個類,如下所示:

class light { 
public: 
    light(const char* light_file, const int n); 
    ~light(); 
    void LoadLight(string light_file); 
//private: 
    int light_num; 
    float **p; 
    float **a; 
    float **d; 
    float **s; 
    float *amb; 
}; 

然後我用光類爲主。 CPP:

light *light_data; 
     ... 
     ... 
    other code 
     ... 
     ... 

void lighting() 
{ 
    // The following lines contain errors 
    GLfloat light_specular[light_data->light_num][4]; //**error line: from here I receive error about light_data, saying that expression must have a constant** value 
    GLfloat light_diffuse[light_data->light_num][4]; //error line 
    GLfloat light_ambient[light_data->light_num][4]; //error line 
    GLfloat light_position[light_data->light_num][4];// error line 
    for(int i = 0; i < light_data->light_num; i++) { 
     int j; 
     for(j = 0; j < 3; j++) { 
      light_specular[i][j] = light_data->s[i][j]; 
      light_diffuse[i][j] = light_data->d[i][j]; 
      light_ambient[i][j] = light_data->a[i][j]; 
      light_position[i][j] = light_data->p[i][j]; 
     } 
     light_specular[i][j] = 1.0f; 
     light_diffuse[i][j] = 1.0f; 
     light_ambient[i][j] = 1.0f; 
     light_position[i][j] = 1.0f; 
    } 
    GLfloat ambient[3]; 
    for(int i = 0; i < 3; i++) { 
     ambient[i] = light_data->amb[i]; 
    } 

在上述照明()函數,它說,light_data必須具有恆定的值。我很困惑這個錯誤,有誰能幫助我? 我是新來的C++,抱歉亂碼。

回答

0
GLfloat light_specular[light_data->light_num][4]; 

這就是所謂的可變長度陣列。這意味着它聽起來像是什麼意思。在這種情況下,第一個維度中的一個或多個維度是可變大小。它們不被C++標準所允許。某些C++實現(特別是g ++)允許VLA語法,但許多實現(特別是Visual Studio)都不支持。

也許是最簡單,最好的標準支持的解決方案是像做

std::vector<std::array<4, GLFloat>> light_specular(light_data->light_num); 

,並得到動態調整大小和在你身邊的作用域存儲器管理,同時保持數據連續性和產生的緩存友好。

Docs on std::vector

Docs on std::array

+0

嗨,謝謝!我會試一試。順便說一句,我不知道如果我在c編譯而不是C++會逃避這個錯誤? – ytutow

+2

@Eric你爲什麼要在'C'開始呢?使用'std :: array'或'std :: vector'並不難。 VLA僅僅是原始數組上的一個步驟 - 如果你超出界限,你會遇到與未定義行爲相同的問題,當VLA以參數的形式傳遞時指向它的衰減等等。 – PaulMcKenzie

+0

@Eric C99標準將編譯它,但VLA變成在C11中是可選的,所以如果給定的編譯器現在允許它,你的猜測就和我一樣好。 VLA很奇怪。他們打破了許多好東西,編譯時常量'sizeof'是一件事,對於一小部分語法糖來說。也是一個殺死你的堆棧的好方法。你或許可以告訴我,我不是一個大的VLA球迷。如果你不得不把你的數組傳遞給一個期望'GLFloat *'或者其他的函數,'std :: vector :: data()'可能會幫你解決。 – user4581301

0

漁獲的是,在C++中,當你創建一個C數組一樣,你需要數組的大小是在編譯時間常數和已知。作爲light_num變量是你的類light_data的成員,它的值不被編譯期間已知的,但是隻有在執行期間(當正在執行的代碼和light_data實例存在於內存中)。

請注意我把我的答案非常通用試圖保持它簡單,而不是深潛水,我只是分享一些其他的計算器職位都是同樣的問題進行了討論:

喔,歡迎C++ :)

+0

謝謝! @diogoslima – ytutow

相關問題