0

I'm trying to make function that initializes VAO on specif index, with some data. The problem is, when I'm accessing the sizeof vertices, return's an wrong size.

Here is the data:

typedef struct {
    GLfloat XYZW[4];
    GLfloat RGBA[4];
} Vertex;

const Vertex Vertices2[] =
{
    { { 0.25f, 0.25f, 0.0f, 1.0f },{ 1.0f, 0.0f, 0.0f, 1.0f } },
    { { 0.75f, 0.25f, 0.0f, 1.0f },{ 0.0f, 1.0f, 0.0f, 1.0f } },
    { { 0.50f, 0.75f, 0.0f, 1.0f },{ 0.0f, 0.0f, 1.0f, 1.0f } }
};
const Vertex Indices2[] = {....}

I call the function like this:

createArrayObjects(0, Vertices2, Indices2);

void createArrayObjects(int index, const Vertex vertices[], const GLubyte indices[]){
    cout << sizeof(vertices) << endl;  ---> returns 4
    cout << sizeof(Vertices2) << endl; ---> returns 96
...
}

If I use sizeof(Vertices2), to fill the VBO, the program runs fine. Without the correct size on the input vertices, I can't fill the VAO and VBO and visualize correctly the data.

Emil Laine
  • 41,598
  • 9
  • 101
  • 157
  • The function arguments specify an array of an unknown size, which is why `sizeof()` doesn't return what you expect. If you're not passing objects that know their own size (eg STL container classes), you'll need to pass an array length as well as the array pointer into the function. – gigaplex Oct 12 '15 at 00:42
  • @gigaplex No, the function argument specifies a _pointer_, which _can_ be an array decayed to a pointer, but [it can also be a pointer which isn't even pointing to an array](http://goo.gl/lIZpmQ). – Emil Laine Oct 12 '15 at 00:54
  • @zenith True, but there's little distinction between an array of unknown length and a pointer. The only real difference is the syntax, and they've used the array syntax in the question. – gigaplex Oct 12 '15 at 01:03
  • 1
    @andre: This rant by Linus Torvalds is very relevant to you: https://lkml.org/lkml/2015/9/3/428 – datenwolf Oct 12 '15 at 09:07

3 Answers3

2

In C++, function parameters of type any_type[] are treated by the compiler as any_type*.

So the type of vertices is really a pointer, and you're getting the size of a pointer with sizeof(vertices).

  • If you need to know the size of the array you pass to a function, you can pass its size as another parameter.
  • Or you can do as vsoftco said, in which case the function template will be instantiated for each different array size you pass to the function.
  • If you want to be "modern" you could also pass an std::array or std::vector, which carry information about their size.
Emil Laine
  • 41,598
  • 9
  • 101
  • 157
  • yes, thats what i just did, when i call the function I added another parameter with the real size –  Oct 12 '15 at 01:21
1

The parameter const Vertext vertices[] you're passing in to the function is essentially a pointer, that's why it's showing up as size 4. You'll have to communicate the size of the array to your function some other way such as by passing in the size as a separate parameter.

You can find more detail in a similar question asked previously here.

Community
  • 1
  • 1
Julian
  • 2,837
  • 17
  • 15
1

Any time you pass an array to a function by value, it decays to a pointer, regardless of the fact that you pass it as arr[] or arr[size], so the size reported by sizeof will be that of a pointer, i.e. in general 4 or 8 bytes. If you want to pass an array and "detect" its size, you can pass it by reference via a template non-type parameter, like in the following simple example:

#include <iostream>

template<typename T, int N>
void f(T(&arr)[N])
{
    std::cout << "Size: " << N;
}

int main()
{
    double arr[10];
    f(arr); // outputs 10
}
vsoftco
  • 55,410
  • 12
  • 139
  • 252