0

i get an error when i doing in the following way:

Firstly I declare a class in file light.cpp as follows:

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

Then I use light class in main.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];
    }

In the above lighting() function, it says that light_data must have constant value. I am so confusing about this error, could anyone help me? I am new to c++, sorry for the messy code.

ytutow
  • 285
  • 1
  • 4
  • 13

2 Answers2

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

This is what's called a Variable Length Array. It means what it sounds like it means. One or more of the dimensions, first one in this case, is a variable size. They aren't allowed by the C++ standard. Some C++ implementations, notably g++, allow VLA syntax but many implementations, notably Visual Studio, do not.

Probably the simplest and best standard-supported solution is to do something like

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

and get dynamic sizing and scoped memory management on your side while maintaining data contiguity and resulting cache friendliness.

Docs on std::vector

Docs on std::array

user4581301
  • 33,082
  • 7
  • 33
  • 54
  • Hi, thank you! I will have a try. By the way, i wonder if i compile this in c instead of c++ will escape this error? – ytutow Nov 30 '16 at 01:41
  • 2
    @Eric Why would you want to start this over in `C`? It isn't that hard to use `std::array` or `std::vector`. A VLA is just one step above raw arrays anyway -- you have the same issues with undefined behavior if you go out of bounds, VLA's decay to pointers when passed as arguments, etc. – PaulMcKenzie Nov 30 '16 at 01:43
  • @Eric C99 standard will compile it, but VLA became optional in C11 so your guess is as good as mine if a given compiler will allow it now. VLAs are... weird. They break a lot of good stuff, compile-time constant `sizeof` for one thing, for a wee bit of syntactic sugar. Also a great way to kill your stack. You can probably tell I'm not a big VLA fan. If you have to take your arrays and pass them into a function expecting `GLFloat *` or somesuch, `std::vector::data()` may come to your rescue. – user4581301 Nov 30 '16 at 01:59
  • Thanks! @user4581301, I have tried both ways and both ways work, although VLAs are still difficult for me to handle well. – ytutow Dec 02 '16 at 09:16
0

the catch is that, on C++, when you are creating a C-style array like that, you need the size of the array to be constant and known during the compilation time. As the light_num variable is a member of your class light_data, its value is not known during compilation, but only during execution (whenever that code is being executed and an instance of light_data exists in memory).

Please notice I kept my answer very generic trying to keep it simple and, instead of deep-diving, I will just share some of the other stackoverflow posts were the same problem is discussed:

Ohh, and welcome to C++ :)

Community
  • 1
  • 1
diogoslima
  • 169
  • 7