C++11 §20.6.5 [ptr.align] remains unimplemented. Several years ago I published what now appears to be a compliant implementation, but it was under the MIT license. Does that disqualify that code, or me, from submitting a patch? As pure, relatively agnostic pointer arithmetic it doesn't seem to fit into the other groups of functions specified for <memory>, which are implemented in various separate files.
Oh, here's a link to my version: http://code.google.com/p/c-plus/source/browse/src/util.h#50
(In reply to David Krauss from comment #0) > C++11 §20.6.5 [ptr.align] remains unimplemented. > > Several years ago I published what now appears to be a compliant > implementation, but it was under the MIT license. Does that disqualify that > code, or me, from submitting a patch? Not at all, nothing stops you (as the author) submitting it to the FSF under the GPL, but to accept it the FSF usually need a copyright asignment on file - do you have one?
Greetings, Any chance to get std::align() implementation included in the coming GCC releases? What needs to be done for that?
Hmm, I recall preparing to submit a patch but not being able to decide which header to modify. Here's the aforementioned MIT-licensed code. The MIT license only requires attribution which is satisfied by the changelog; anyway I don't care. I am already a GNU contributor with FSF waiver back in 2009. This code should probably be reviewed. I wrote it a long time ago and seldom used it. Cannot recall whether it was intended to be 100% compliant. inline void *align( std::size_t alignment, std::size_t size, void *&ptr, std::size_t &space ) { auto pn = reinterpret_cast< std::size_t >( ptr ); auto aligned = ( pn + alignment - 1 ) & - alignment; auto new_space = space - ( aligned - pn ); if ( new_space < size ) return nullptr; space = new_space; return ptr = reinterpret_cast< void * >( aligned ); }
Just re-reading now, std::size_t should be std::uintptr_t, but I don't see anything else that could cause UB. The bitwise "negative" arithmetic should be OK because it's all on unsigned values. And if GNU style doesn't allow auto, those should just be uintptr_t or size_t as appropriate.
(In reply to David Krauss from comment #5) > Just re-reading now, std::size_t should be std::uintptr_t, but I don't see > anything else that could cause UB. The bitwise "negative" arithmetic should > be OK because it's all on unsigned values. > > And if GNU style doesn't allow auto, those should just be uintptr_t or > size_t as appropriate. This code looks fine to me at my best knowledge of expected std::align() behaviour. I also tried it against the artificial test case described at https://stackoverflow.com/questions/16305311/usage-issue-of-stdalign and it doesn't re-align the already aligned pointer. Not sure if auto keyword is prohibited by GCC internal code style, perhaps someone from GCC devs could help on that. Thank you for preparing the fix, David!
Haha, it looks like the MSVC devs forgot to subtract 1. Typical. I did test my code in a real arena allocator, by the way, so that sort of thing would not have gotten through.
(In reply to Vladimir Krivopalov from comment #3) > Any chance to get std::align() implementation included in the coming GCC > releases? > What needs to be done for that? It's too late for GCC 4.9 now.
Whoa, there's a nasty bug there, if alignment > space. inline void *align( std::size_t alignment, std::size_t size, void *&ptr, std::size_t &space ) { std::uintptr_t pn = reinterpret_cast< std::uintptr_t >( ptr ); std::uintptr_t aligned = ( pn + alignment - 1 ) & - alignment; size += aligned - pn; // Add padding to size. if ( space < size ) return nullptr; space -= size; return ptr = reinterpret_cast< void * >( aligned ); } I haven't tested this edit at all.
Confirmed as unimplemented.
No, that code wasn't right either. I'll just leave it at this and a caveat to the reader: inline void *align( std::size_t alignment, std::size_t size, void *&ptr, std::size_t &space ) { std::uintptr_t pn = reinterpret_cast< std::uintptr_t >( ptr ); std::uintptr_t aligned = ( pn + alignment - 1 ) & - alignment; std::size_t padding = aligned - pn; if ( space < size + padding ) return nullptr; space -= padding; return ptr = reinterpret_cast< void * >( aligned ); }
Author: redi Date: Mon Oct 13 14:08:44 2014 New Revision: 216149 URL: https://gcc.gnu.org/viewcvs?rev=216149&root=gcc&view=rev Log: PR libstdc++/57350 * include/std/memory (align): Do not adjust correctly aligned address. * testsuite/20_util/align/2.cc: New. Added: trunk/libstdc++-v3/testsuite/20_util/align/2.cc Modified: trunk/libstdc++-v3/ChangeLog trunk/libstdc++-v3/include/std/memory
Fixed on trunk.