google / mathfu

C++ math library developed primarily for games focused on simplicity and efficiency.
http://google.github.io/mathfu
Apache License 2.0
1.4k stars 188 forks source link

Including quaternion.h after including vector.h can cause template errors #18

Closed ettoretorti closed 7 years ago

ettoretorti commented 7 years ago

If you include quaternion.h after including vector.h and instantiating a Vector<float, 3>, you get template errors.

Here's a small example to illustrate this happening.

myheader.h

#pragma once

#include <mathfu/vector.h>

struct MyStruct {
    mathfu::Vector<float, 3> myVec;
};

main.cpp

#include "myheader.h"
#include <mathfu/quaternion.h>

int main() {
    return 0;
}

Trying to compile main.cpp with g++ will result in these errors:

$ g++ -I./include main.cpp 
In file included from ./include/mathfu/matrix.h:22:0,
                 from ./include/mathfu/quaternion.h:25,
                 from main.cpp:2:
./include/mathfu/vector_3.h:66:7: error: specialization of ‘mathfu::Vector<float, 3>’ after instantiation
 class Vector<float, 3> {
       ^
./include/mathfu/vector_3.h:66:7: error: redefinition of ‘class mathfu::Vector<float, 3>’
In file included from myheader.h:3:0,
                 from main.cpp:1:
./include/mathfu/vector.h:151:7: error: previous definition of ‘class mathfu::Vector<float, 3>’
 class Vector {
       ^
./include/mathfu/vector.h: In constructor ‘mathfu::Vector<float, 4>::Vector(const mathfu::Vector<float, 3>&, const float&)’:
./include/mathfu/vector.h:679:12: error: ‘float mathfu::Vector<float, 3>::data_ [3]’ is private
   T data_[d];
            ^
In file included from ./include/mathfu/matrix.h:23:0,
                 from ./include/mathfu/quaternion.h:25,
                 from main.cpp:2:
./include/mathfu/vector_4.h:73:26: error: within this context
     data_.simd = vector3.data_.simd;
                          ^
./include/mathfu/vector_4.h:73:32: error: request for member ‘simd’ in ‘vector3.mathfu::Vector<float, 3>::data_’, which is of non-class type ‘const float [3]’
     data_.simd = vector3.data_.simd;
jsanmiya commented 7 years ago

Hi Ettore,

You're right.

We have SIMD specializations of some common Vectors (such as Vector<float,3>). Those SIMD specializations are in separate files, however. It's possible to use the non-specialized Vectors before #including the SIMD specialization files, unfortunately. That's the error you're seeing.

I've refactored the headers so that the specializations are included with,

include <mathfu/vector.h>

We'll push that change in the next point release, but for now you can work around your compile error by including the specialization directly. That is, use this instead:

include <mathfu/vector_3.h>

Thanks for pointing this out! Jason

On Wed, Aug 10, 2016 at 11:35 AM, Ettore Torti notifications@github.com wrote:

If you include quaternion.h after including vector.h and instantiating a Vector<float, 3>, you get template errors.

Here's a small example to illustrate this happening.

myheader.h

pragma once

include <mathfu/vector.h>

struct MyStruct { mathfu::Vector<float, 3> myVec; };

main.cpp

include "myheader.h"

include <mathfu/quaternion.h>

int main() { return 0; }

Trying to compile main.cpp with g++ will result in these errors:

$ g++ -I./include main.cpp In file included from ./include/mathfu/matrix.h:22:0, from ./include/mathfu/quaternion.h:25, from main.cpp:2: ./include/mathfu/vector_3.h:66:7: error: specialization of ‘mathfu::Vector<float, 3>’ after instantiation class Vector<float, 3> { ^ ./include/mathfu/vector3.h:66:7: error: redefinition of ‘class mathfu::Vector<float, 3>’ In file included from myheader.h:3:0, from main.cpp:1: ./include/mathfu/vector.h:151:7: error: previous definition of ‘class mathfu::Vector<float, 3>’ class Vector { ^ ./include/mathfu/vector.h: In constructor ‘mathfu::Vector<float, 4>::Vector(const mathfu::Vector<float, 3>&, const float&)’: ./include/mathfu/vector.h:679:12: error: ‘float mathfu::Vector<float, 3>::data [3]’ is private T data_[d]; ^ In file included from ./include/mathfu/matrix.h:23:0, from ./include/mathfu/quaternion.h:25, from main.cpp:2: ./include/mathfu/vector4.h:73:26: error: within this context data.simd = vector3.data_.simd; ^ ./include/mathfu/vector4.h:73:32: error: request for member ‘simd’ in ‘vector3.mathfu::Vector<float, 3>::data’, which is of non-class type ‘const float [3]’ data.simd = vector3.data.simd;

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/google/mathfu/issues/18, or mute the thread https://github.com/notifications/unsubscribe-auth/AF3McGfTrMyPMXT4afx0tJJj_GPJF88Dks5qehnXgaJpZM4JhcXR .

jsanmiya commented 7 years ago

Actually, we just pushed to github, so if you grab the latest, your code should work now.

FYI, here's the fix: https://github.com/google/mathfu/commit/7a5a6ef215582e63f7216e7dcdc1a93ee409e0d7

On Wed, Aug 10, 2016 at 6:03 PM, Jason Sanmiya jsanmiya@google.com wrote:

Hi Ettore,

You're right.

We have SIMD specializations of some common Vectors (such as Vector<float,3>). Those SIMD specializations are in separate files, however. It's possible to use the non-specialized Vectors before #including the SIMD specialization files, unfortunately. That's the error you're seeing.

I've refactored the headers so that the specializations are included with,

include <mathfu/vector.h>

We'll push that change in the next point release, but for now you can work around your compile error by including the specialization directly. That is, use this instead:

include <mathfu/vector_3.h>

Thanks for pointing this out! Jason

On Wed, Aug 10, 2016 at 11:35 AM, Ettore Torti notifications@github.com wrote:

If you include quaternion.h after including vector.h and instantiating a Vector<float, 3>, you get template errors.

Here's a small example to illustrate this happening.

myheader.h

pragma once

include <mathfu/vector.h>

struct MyStruct { mathfu::Vector<float, 3> myVec; };

main.cpp

include "myheader.h"

include <mathfu/quaternion.h>

int main() { return 0; }

Trying to compile main.cpp with g++ will result in these errors:

$ g++ -I./include main.cpp In file included from ./include/mathfu/matrix.h:22:0, from ./include/mathfu/quaternion.h:25, from main.cpp:2: ./include/mathfu/vector_3.h:66:7: error: specialization of ‘mathfu::Vector<float, 3>’ after instantiation class Vector<float, 3> { ^ ./include/mathfu/vector3.h:66:7: error: redefinition of ‘class mathfu::Vector<float, 3>’ In file included from myheader.h:3:0, from main.cpp:1: ./include/mathfu/vector.h:151:7: error: previous definition of ‘class mathfu::Vector<float, 3>’ class Vector { ^ ./include/mathfu/vector.h: In constructor ‘mathfu::Vector<float, 4>::Vector(const mathfu::Vector<float, 3>&, const float&)’: ./include/mathfu/vector.h:679:12: error: ‘float mathfu::Vector<float, 3>::data [3]’ is private T data_[d]; ^ In file included from ./include/mathfu/matrix.h:23:0, from ./include/mathfu/quaternion.h:25, from main.cpp:2: ./include/mathfu/vector4.h:73:26: error: within this context data.simd = vector3.data_.simd; ^ ./include/mathfu/vector4.h:73:32: error: request for member ‘simd’ in ‘vector3.mathfu::Vector<float, 3>::data’, which is of non-class type ‘const float [3]’ data.simd = vector3.data.simd;

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/google/mathfu/issues/18, or mute the thread https://github.com/notifications/unsubscribe-auth/AF3McGfTrMyPMXT4afx0tJJj_GPJF88Dks5qehnXgaJpZM4JhcXR .

ettoretorti commented 7 years ago

Thanks for dealing with this so quickly :)