Tuesday, 19 July 2016

C++ alignment of class - member call on misaligned address



I'm using UBSAN and am getting the following error. Note that I'm compiling with clang 6.0.1 with -fsanitize=undefined. I've read a number of background questions on SO and still can't solve my particular issue. Here are the background questions for reference:





Here are some things to note about class C:





  • the object of type C is created using new (C* o = new C();)

  • type C has a member of type A that has 64 byte alignment. I verified this using alignof.

  • C is declared using class alignas(64) C -- but that doesn't solve my problem



My current hypothesis is that I need to use the C++11 equivalent of the C++17 std::aligned_alloc to create the object using aligned storage. But, I'm not sure how to best do this or if it will actually solve my problem. I would prefer to solve the problem once in the definition of class C as opposed to every time I create a C, if possible. What is the recommended approach to solve this issue to remove the UBSAN error?


Answer



If your class already has a member that requires 64 Byte alignment, then the class will already also have 64 Byte alignment out of necessity. So adding an explicit alignas(64) is not really gonna change anything.




The basic problem here is that allocation functions (in C++11) are only required to return memory aligned to fundamental alignment. C++11 left it implementation-defined whether over-aligned types are supported by new or not [expr.new]/1. C++17 introduced new-extended alignment and additional allocation functions to deal with that (if and which new-extended alignments are supported, however, is still implementation-defined).



If you can switch to a compiler that supports C++17, chances are that your code will just work. Otherwise you will probably have to either use some implementation-specific function to allocate aligned memory or just roll your own solution, e.g., based on std::align and placement new (which would work in C++11 too)…


No comments:

Post a Comment

c++ - Does curly brackets matter for empty constructor?

Those brackets declare an empty, inline constructor. In that case, with them, the constructor does exist, it merely does nothing more than t...