[PATCH] c++, libstdc++, v2: Implement C++26 P3074R7, P3726R0 and CWG3189 - trivial unions [PR119059]

Jakub Jelinek jakub@redhat.com
Thu May 21 08:50:53 GMT 2026


On Thu, May 21, 2026 at 10:31:25AM +0200, Tomasz Kaminski wrote:
> Even with this patch, I still see a difference between the foo and bar
> functions.
> as defined below:
> #include <memory>
> #include <cassert>
> #include <string>
> 
> template <typename T, size_t N>
> struct FixedVector {
>   union { T storage[N]; };
>   size_t size = 0;
> 
>   constexpr FixedVector () { std::start_lifetime (storage); }
> 
>   constexpr ~FixedVector() { std::destroy(storage, storage + size); }
> 
>   constexpr FixedVector(std::initializer_list<T> il)
>   {
>     assert(il.size() < N);
>     std::start_lifetime (storage);
>     std::uninitialized_copy(il.begin(), il.end(), storage);
>     size = il.size();
>   }
> 
>   constexpr void push_back(T const& v) { ::new (storage + size) T(v);
> ++size; }
> };
> 
> FixedVector<char, 4> foo()
> {
>   return {'a', 'b', 'c'};
> }
> 
> FixedVector<char, 4> bar()
> {
>   constexpr FixedVector<char, 4> res{'a', 'b', 'c'};
>   return res;
> }
> 
> After compiling the above with -O2 I see:

This boils down to the differences in C with -O2 on:
struct S { unsigned char a[4]; unsigned long b; };

struct S foo () { static const unsigned char c[3] = { 97, 98, 99 }; struct S r; __builtin_memcpy (&r.a, &c, 3); r.b = 3; return r; }
struct S bar () { struct S r; r.a[0] = 97; r.a[1] = 98; r.a[2] = 99; r.b = 3; return r; }
struct S baz () { static const unsigned char c[4] = { 97, 98, 99, 100 }; struct S r; __builtin_memcpy (&r.a, &c, 4); r.b = 4; return r; }
struct S qux () { struct S r; r.a[0] = 97; r.a[1] = 98; r.a[2] = 99; r.a[3] = 100; r.b = 4; return r; }

Note, baz and qux emit the same
	movl	$4, %edx
	movl	$1684234849, %eax
while
	movzbl	.LC0+1(%rip), %edx
	movzbl	.LC0(%rip), %eax
	salq	$8, %rdx
	orq	%rax, %rdx
	movzbl	.LC0+2(%rip), %eax
	salq	$16, %rax
	orq	%rdx, %rax
	movl	$3, %edx
	ret
vs.
	movl	$3, %edx
	movl	$6513249, %eax
	ret
I guess worth filing a PR, but I'm afraid we have plenty of prior PRs
about this too (and some attempt to improve it but not really successful;
it is about the returning of uninitialized bits in registers).

	Jakub



More information about the Libstdc++ mailing list