POD
David Nadlinger
see at klickverbot.at
Fri Dec 28 17:53:13 PST 2012
On Friday, 28 December 2012 at 22:40:13 UTC, Walter Bright wrote:
> D's definition of POD: […]
The definition of POD as used in the x86-64 System V ABI – and
its implementation is really the only place where isPOD matters
right now – is as follows (ver. 0.99.6):
"If a C++ object has either a non-trivial copy constructor or a
non-trivial
destructor, it is passed by invisible reference […]."
and as a footnote:
"A de/constructor is trivial if it is an implicitly-declared
default de/constructor and if:
- its class has no virtual functions and no virtual base
classes, and
- all the direct base classes of its class have trivial
de/constructors, and
- for all the nonstatic data members of its class that are of
class type (or array thereof), each such class has a trivial
de/constructor."
Note that the absence of a constructor is *not* required for a
C++ class/struct to be considered POD under the rules of the
x86-64 ABI. I would want to be *very* sure about my reasons
before changing this behavior as it will definitely lead to
confusion, especially considering that ABI details are black
magic to many programmers anyway.
In fact, I had been planning to ping you about this since I
started to work on the LDC ABI implementation a few months ago (a
place where this makes a difference are e.g. some types from
core.time), but I then shifted my focus more towards resolving
the immediate release blocker issues and apparently in turn also
forgot to raise this issue on the mailing list.
Anyway, I would ask you to reconsider your decision because:
- It breaks the principle of least surprise regarding the C<->D
mapping: While you can add adornments like constructors to the
C++ definition of a given C type, you can't in D. Also, as
mentioned by Andrej, as a programmer you just don't expect a
constructor to make your struct somehow behave differently than a
plain C struct.
- More or less another way of stating the last point, it is not
at all obvious from the x86-64 ABI specification: I
re-implemented the x86-64 ABI for D from scratch for LDC
recently, and this was just about the only difference between
your implementation and mine (the other, as far as I remember,
being that DMD mistakenly never enregisters 3-byte structs).
Sure, we need to properly document the D behavior anyway, but if
the general rule is "D follows the ABI of the host C compiler", I
think we should avoid diverting from the obvious path as much as
possible.
- The new C++ standard defines POD structs as being "a non-union
class that is both a trivial class and a standard-layout class,
and has no
non-static data members of type non-POD struct, non-POD union (or
array of such types)" ([class]p10), where "trivial" means no
copy/move constructors or destructors, and standard-layout
essentially excludes virtuals, different access control modifiers
and base classes with non-static fields. In particular, POD
structs are allowed to have constructors, and going a different
route with D will likely be a source of confusion.
- There are also possible performance implications: Structs that
just wrap a single field in order to enrich it with type
information, such as Duration or a Quantity struct from a units
of measurement library, will likely benefit from being passed in
registers (if available), even if they will probably have
constructors. In fact, having such one-field structs behave like
a naked value might be vitally important to be able to decorate a
C API with e.g. units information (even if such code would
strictly speaking be architecture dependent).
As far as I can see – and I'm merely guessing based on the isPOD
comment here – the only reason for not just applying the C/C++
definition in the obvious way might be a quirk in the DMD backend
implementation?
David
More information about the Digitalmars-d
mailing list