2

I found the following C++ code with syntax I have never before seen. Does anybody care to elaborate how this workss?

Function 1

glm::vec3 BottomCircleOffset(float fElapsedTime)
{
    return glm::vec3(.0f,.0f,.0f);
}

Function 2

glm::vec3 OvalOffset(float fElapsedTime)
{
    return glm::vec3(.1f, .1f, .1f);
}

Instance Struct

struct Instance
{
    typedef glm::vec3(*OffsetFunc)(float);

    OffsetFunc CalcOffset;

    glm::mat4 ConstructMatrix(float fElapsedTime)
    {
        glm::mat4 theMat(1.0f);
        theMat[3] = glm::vec4(CalcOffset(fElapsedTime), 1.0f);
        return theMat;
    }
};

Until now this is all fine. I understand OffsetFunc is a typedef for a function pointer taking a float as argument and returning a glm::vec3. I also understand CalcOffset is a variable to such a function.

The code then goes to create an array of Instance types like so:

Instance g_instanceList[] =
{
    {StationaryOffset},
    {OvalOffset},
    {BottomCircleOffset},
};

This is syntax I have never come across before:

  • How are we initialising an Instance type by simply putting the name of a function?
  • The Instance struct not even having a constructor which takes a function pointer, how does it know to initialise CalcOffset to this value?
3
  • the name of a function is a pointer to that function. Commented Apr 16, 2014 at 12:48
  • 2
    This is aggregate initialization. Look it up. Commented Apr 16, 2014 at 12:49
  • @HennoBrandsma: No, it isn't. It converts to one. This matters, because a function may be overloaded, and then one name can convert to two or more distinct pointers. Commented Apr 16, 2014 at 14:31

2 Answers 2

5

Instance is an aggregate - it contains public data members, but no constructors, destructors or other complications, so can (in many ways) be treated like a struct in C.

In particular, it can be aggregate-initialised, by specifying a list of values for the members enclosed in braces. A simple example:

struct s {int a,b,c;};
s example = {1,2,3};    // initialises a=1, b=2, c=3

Arrays can also be aggregate-initialised:

int a[3] = {1,2,3};

and, if the array members are aggregates, then each of them can be aggregate-initialised in turn:

s a[3] = {{1,2,3},{4,5,6},{7,8,9}};

Your example is the same as this: each Instance in the array is aggregate-initialised, using the provided function pointer to initialise the CalcOffset member.

Sign up to request clarification or add additional context in comments.

Comments

1

This is a regular C-style initialization of a struct. Recall that you can initialize an array of structs like this:

struct x {
    int a;
};
x data[] = {{1}, {2}, {3}};

Your code uses the same syntax, but with a function pointer in place of an int.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.