Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 20 Feb 2025 11:03:28 +0000
From:      David Chisnall <theraven@FreeBSD.org>
To:        Poul-Henning Kamp <phk@phk.freebsd.dk>
Cc:        current@freebsd.org
Subject:   Re: Empty structures have sizeof(1) in C++ now ?
Message-ID:  <9A5B431C-2405-412A-90FF-DA016E80DF68@FreeBSD.org>
In-Reply-To: <202502200940.51K9eswS003142@critter.freebsd.dk>
References:  <202502200940.51K9eswS003142@critter.freebsd.dk>

next in thread | previous in thread | raw e-mail | index | archive | help
No, that=E2=80=99s always been the case in C++.  It comes from the rule =
that two allocations must have unique addresses.  If a structure could =
have size zero, an array of these structures would have size zero and =
the two elements in the array would have the same address.  Similarly, =
two struct fields could have the same address, which breaks other bits =
of the language (pointers to members would compare equal when they =
should not).

C++20 introduced the no_unique_address attribute.  This allows you to =
embed a struct in another and, if the child struct has no fields, then =
its address is not required to be unique and you are explicitly saying =
that you won=E2=80=99t do any of the things where this would be a =
problem. =20

This lets you do things like:

```c++
template<typename Embedded=3Dvoid>
struct SomeStructThatMayContainAnother
{
	// Normal fields go here

	[[no_unique_address]]
	std::conditional_t<std::is_same_v<Embedded, void>, struct {}, =
Embedded> embeddedStruct;

	// More fields maybe here
};
```

In this case, `embeddedStruct` will not add any space to the parent =
struct if the template parameter is `void`.

David

> On 20 Feb 2025, at 09:40, Poul-Henning Kamp <phk@phk.freebsd.dk> =
wrote:
>=20
> Is this a bug ?
>=20
>=20
> critter phk> cat /tmp/_.c
>=20
> #include <stdio.h>
> struct foo {
> };
>=20
> int
> main(int argc, char **argv)
> {
> struct foo bar;
> printf("%jd %jd\n", sizeof(struct foo), sizeof(bar));
> return (0);
> }
> critter phk> cc -o /tmp/a.out /tmp/_.c
> critter phk> /tmp/a.out
> 0 0
> critter phk> c++ -o /tmp/a.out /tmp/_.c
> c++: warning: treating 'c' input as 'c++' when in C++ mode, this =
behavior is deprecated [-Wdeprecated]
> critter phk> /tmp/a.out
> 1 1
>=20
> --=20
> Poul-Henning Kamp       | UNIX since Zilog Zeus 3.20
> phk@FreeBSD.ORG         | TCP/IP since RFC 956
> FreeBSD committer       | BSD since 4.3-tahoe
> Never attribute to malice what can adequately be explained by =
incompetence.
>=20
>=20




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?9A5B431C-2405-412A-90FF-DA016E80DF68>