Hi, I would like to reopen the discussion for pr/15795, or at least get clarification on the current resolution of WONTFIX. http://gcc.gnu.org/bugzilla/show_bug.cgi?id=15795
Let me state right at the beginning that I am also volunteering to do the actual work to come up with an agreed solution and implement it. Briefly, pr/15795 was submitted to address the issue of calling the new operator for a class which has an alignment greater than that guaranteed by the underlying malloc(). It specifically talks about alignment for vector types, but it applies to any alignment. For example, a 16 byte vector type typically requires 16 byte alignment and malloc() might only guarantee 8 byte alignment. When a class contains that vector the class requires alignment of 16, but a new operator that calls that malloc() will not always return properly aligned memory. The pr proposes some solutions: solution: operator new should always return 16 byte aligned memory response: glibc doesn't do that, neither should libstdc++ I agree with this response. A solution that handles any alignment is better, simply changing the default isn't sufficient. solution: create an additional signature for operator new which has a parameter that indicates the alignment. The compiler should call this version of the operator when necessary and the standard library should provide an appropriate implementation. response: "would interact badly with overriding the default operator new." At first glance, this could break some existing code, but I think this solution could be made to work. I'll discuss below. solution: the library will provide an implementation of a new operator with an additional parameter, but the user is responsible for calling it. response: doesn't work well with existing template class libraries, like STL or Qt. I agree with this response. (There was no agreement or disagreement with this response in the pr.) For the second proposed solution, let's define precisely the cases that "interact badly". I can think of only one case, defined by these conditions: - a type has an alignment greater than what malloc() guarantees - operator new for that type does not call the default implementation for operator new - an object of that type is created using operator new - an appropriate implementation of operator new with the additional alignment parameter is not provided for this type. Clearly, if the compiler does not call the user defined version of operator new in this case, the code is likely to break. Are there other cases which "interact badly"? I'm hoping a solution to this case is as simple as: - when the compiler would call the aligned version of operator new it first checks which definition of operator new would have been called if it were not aligned. If there is an aligned version of operator new in the same place*, call it, otherwise call the non-aligned version and issue a warning. (* for "place" fill in the appropriate C++ jargon for it to make sense, e.g., namespace, class, scope.) - the default versions of operator new and the aligned version of operator new should be defined in the same section. That way, when a user overrides the default operator new, they will get a link error (duplicate definitions of new) unless they also define the aligned version of operator new. Can anyone identify situations where this wouldn't work? In the case where it generates a warning the code might not work because of improper alignment, but at that point I would consider it the users problem. While I'm here let me also point out that an object which is allocated on the stack and has alignment greater than what the stack guarantees is also an issue. I have a patch which fixes this for any alignment, though it doesn't take advantage of stack ordering. Thanks, Trevor