1*bf2c3715SXin Linamespace Eigen { 2*bf2c3715SXin Li 3*bf2c3715SXin Li/** \eigenManualPage TopicWrongStackAlignment Compiler making a wrong assumption on stack alignment 4*bf2c3715SXin Li 5*bf2c3715SXin Li<h4>It appears that this was a GCC bug that has been fixed in GCC 4.5. 6*bf2c3715SXin LiIf you hit this issue, please upgrade to GCC 4.5 and report to us, so we can update this page.</h4> 7*bf2c3715SXin Li 8*bf2c3715SXin LiThis is an issue that, so far, we met only with GCC on Windows: for instance, MinGW and TDM-GCC. 9*bf2c3715SXin Li 10*bf2c3715SXin LiBy default, in a function like this, 11*bf2c3715SXin Li 12*bf2c3715SXin Li\code 13*bf2c3715SXin Livoid foo() 14*bf2c3715SXin Li{ 15*bf2c3715SXin Li Eigen::Quaternionf q; 16*bf2c3715SXin Li //... 17*bf2c3715SXin Li} 18*bf2c3715SXin Li\endcode 19*bf2c3715SXin Li 20*bf2c3715SXin LiGCC assumes that the stack is already 16-byte-aligned so that the object \a q will be created at a 16-byte-aligned location. For this reason, it doesn't take any special care to explicitly align the object \a q, as Eigen requires. 21*bf2c3715SXin Li 22*bf2c3715SXin LiThe problem is that, in some particular cases, this assumption can be wrong on Windows, where the stack is only guaranteed to have 4-byte alignment. Indeed, even though GCC takes care of aligning the stack in the main function and does its best to keep it aligned, when a function is called from another thread or from a binary compiled with another compiler, the stack alignment can be corrupted. This results in the object 'q' being created at an unaligned location, making your program crash with the \ref TopicUnalignedArrayAssert "assertion on unaligned arrays". So far we found the three following solutions. 23*bf2c3715SXin Li 24*bf2c3715SXin Li 25*bf2c3715SXin Li\section sec_sol1 Local solution 26*bf2c3715SXin Li 27*bf2c3715SXin LiA local solution is to mark such a function with this attribute: 28*bf2c3715SXin Li\code 29*bf2c3715SXin Li__attribute__((force_align_arg_pointer)) void foo() 30*bf2c3715SXin Li{ 31*bf2c3715SXin Li Eigen::Quaternionf q; 32*bf2c3715SXin Li //... 33*bf2c3715SXin Li} 34*bf2c3715SXin Li\endcode 35*bf2c3715SXin LiRead <a href="http://gcc.gnu.org/onlinedocs/gcc-4.4.0/gcc/Function-Attributes.html#Function-Attributes">this GCC documentation</a> to understand what this does. Of course this should only be done on GCC on Windows, so for portability you'll have to encapsulate this in a macro which you leave empty on other platforms. The advantage of this solution is that you can finely select which function might have a corrupted stack alignment. Of course on the downside this has to be done for every such function, so you may prefer one of the following two global solutions. 36*bf2c3715SXin Li 37*bf2c3715SXin Li 38*bf2c3715SXin Li\section sec_sol2 Global solutions 39*bf2c3715SXin Li 40*bf2c3715SXin LiA global solution is to edit your project so that when compiling with GCC on Windows, you pass this option to GCC: 41*bf2c3715SXin Li\code 42*bf2c3715SXin Li-mincoming-stack-boundary=2 43*bf2c3715SXin Li\endcode 44*bf2c3715SXin LiExplanation: this tells GCC that the stack is only required to be aligned to 2^2=4 bytes, so that GCC now knows that it really must take extra care to honor the 16 byte alignment of \ref TopicFixedSizeVectorizable "fixed-size vectorizable Eigen types" when needed. 45*bf2c3715SXin Li 46*bf2c3715SXin LiAnother global solution is to pass this option to gcc: 47*bf2c3715SXin Li\code 48*bf2c3715SXin Li-mstackrealign 49*bf2c3715SXin Li\endcode 50*bf2c3715SXin Liwhich has the same effect than adding the \c force_align_arg_pointer attribute to all functions. 51*bf2c3715SXin Li 52*bf2c3715SXin LiThese global solutions are easy to use, but note that they may slowdown your program because they lead to extra prologue/epilogue instructions for every function. 53*bf2c3715SXin Li 54*bf2c3715SXin Li*/ 55*bf2c3715SXin Li 56*bf2c3715SXin Li} 57