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