Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initializer list constructors cause ambiguity and runtime errors #159

Closed
johnbartholomew opened this issue Jan 21, 2014 · 9 comments
Closed
Assignees
Labels
Milestone

Comments

@johnbartholomew
Copy link

Prior to the introduction of the initalizer-list constructors, this code creates an identity quaternion:

glm::quat{1.0f, 0.0f, 0.0f, 0.0f}

After the introduction of the initializer-list constructors, the same code creates a different quaternion (setting x=1 and w=0, whereas before it set w=1, x=0). This does not result in any compile time error or warning, because the code is still correct, it just results in a bug at runtime.

Prior to the introduction of the initializer-list constructors, this code creates an identity matrix:

glm::mat4{1.0f}

After the introduction of the initializer-list constructors, the same code compiles but causes an assertion failure at runtime.

This seems to me to be a step backwards in usability, introducing ambiguity and reducing the effectiveness of compiler type checking in confirming that the API is being used correctly. Note that the uniform initialization syntax is recommended by people such as Herb Sutter for general use (see, Elements of Modern C++ Style); ie, it is not strange to use it by default in C++11 (it's not intended only for initializer lists).

If you guess that I'm writing this issue because I've just been stung by these problems, you are correct.

@ghost ghost assigned Groovounet Jan 21, 2014
@Groovounet
Copy link
Member

So what would be your recommended resolution here?

@johnbartholomew
Copy link
Author

So what would be your recommended resolution here?

That depends on why the initializer-list constructors were added in the first place. It's not obvious to me why they're needed (or useful) here at all, but I'm sure there must have been some reason. If there's a good reason for having those constructors then I guess the only thing you can do about it is to make sure the ambiguity is clearly documented.

@TieJu
Copy link

TieJu commented Jan 21, 2014

I posted the same issue a minute ago and overlooked this ... :)

Remove the constructors they are not needed, the compiler will use the closest matching constructor for a uniform initialisation list.

@Groovounet
Copy link
Member

There is actually a point for the initialized lists. It allows to write code like:

std::vector<glm::mat4> v1{
    {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
    {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}
};

std::vector<glm::mat4> v2{
    {
        { 0, 1, 2, 3 },
        { 4, 5, 6, 7 },
        { 8, 9, 10, 11 },
        { 12, 13, 14, 15 }
    },
    {
        { 0, 1, 2, 3 },
        { 4, 5, 6, 7 },
        { 8, 9, 10, 11 },
        { 12, 13, 14, 15 }
    }
};

Which is pretty nice to me.

The ambiguity on glm::mat4{1.0f} is pretty unfortunate. I need to think about it, a fix would be pretty nice.

@johnbartholomew
Copy link
Author

I'm not sure you need initializer-list constructors on glm objects to be able to do that, I think you only need the one on std::vector. See this gist, for example: https://gist.github.com/johnbartholomew/8550473

Edit: I don't know whether it works in the context of the kind of templated constructors that glm uses/would want to use. It's also possible that it relies on some non-standard type deduction behaviour. Further investigation may be needed.

@TiagoRabello
Copy link

Yes, @johnbartholomew is actually right.
Initializer-list constructors are not needed if you want to be able to initialize matrix that way, @Groovounet.
Here is a working example of it using only constructors similar to what Matrix4x4 has:
http://ideone.com/ZlfCoZ

@Groovounet Groovounet added the bug label Feb 6, 2014
@Groovounet Groovounet added this to the GLM 0.9.5 milestone Feb 6, 2014
@Groovounet
Copy link
Member

Well in practice if I disable the initializer_list contructors and compile the core_type_mat4x4.cpp unit tests I get the following errors:

/Users/christophericcio/Documents/Repository/Github/glm/test/core/core_type_mat4x4.cpp:203:12:
No matching constructor for initialization of 'glm::mat4' (aka 'tmat4x4<float, highp>')
/Users/christophericcio/Documents/Repository/Github/glm/test/core/core_type_mat4x4.cpp:215:25: No matching constructor for initialization of 'std::vectorglm::mat4'

/Users/christophericcio/Documents/Repository/Github/glm/test/core/core_type_mat4x4.cpp:230:25: No matching constructor for initialization of 'std::vectorglm::mat4'

/Users/christophericcio/Documents/Repository/Github/glm/test/core/core_type_mat4x4.cpp:235:25: No matching constructor for initialization of 'std::vectorglm::mat4'

This was tested on Apple LLVM version 5.0 (clang-500.2.79) (based on LLVM 3.3svn).

I also tested the behaviour of VC13 and it's very similar.

Thanks,
Christophe

@TieJu
Copy link

TieJu commented Feb 8, 2014

Same text as for ticket #160:
You need to remove the 'explicit'ness of many constructors that are needed to do the initialization of mat4 and vec4, then it will work.
Explicit is only needed for one parameter constructors to prohibit transformations from one type to an other, like from a single int to a vec or matrix, what is clearly not desired, for multi-param constructors this makes the constructors unusable for such desired transformations.

@Groovounet
Copy link
Member

This issue is fixed in GLM 0.9.5 branch for next.

I removed the initializer_list constructors and removed some explicit constructors.

Thanks for contributing,
Christophe

mosra added a commit to mosra/magnum-integration that referenced this issue May 31, 2018
Read the comment for a good horror story and the following issue for a
good laugh. Everything would be good if 0.9.5.1 was long forgotten in
the years past, but for some reason it is *the* version included in
Ubuntu 14.04 LTS that has EOL in April *next year*.

This gave me cancer.

g-truc/glm#159
mosra added a commit to mosra/magnum-integration that referenced this issue May 31, 2018
Read the comment for a good horror story and the following issue for a
good laugh. Everything would be good if 0.9.5.1 was long forgotten in
the years past, but for some reason it is *the* version included in
Ubuntu 14.04 LTS that has EOL in April *next year*.

This gave me cancer.

g-truc/glm#159
mosra added a commit to mosra/magnum-integration that referenced this issue May 31, 2018
Read the comment for a good horror story and the following issue for a
good laugh. Everything would be good if 0.9.5.1 was long forgotten in
the years past, but for some reason it is *the* version included in
Ubuntu 14.04 LTS that has EOL in April *next year*.

This gave me cancer.

g-truc/glm#159
mosra added a commit to mosra/magnum-integration that referenced this issue Jun 1, 2018
Read the comment for a good horror story and the following issue for a
good laugh. Everything would be good if 0.9.5.1 was long forgotten in
the years past, but for some reason it is *the* version included in
Ubuntu 14.04 LTS that has EOL in April *next year*.

This gave me cancer.

g-truc/glm#159
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants