RFC: Update Intel386, x86-64 and IA MCU psABIs for passing/returning empty struct

Matthijs van Duin via cfe-commits cfe-commits at lists.llvm.org
Thu Feb 11 02:47:29 PST 2016


On 8 February 2016 at 22:40, H.J. Lu <hjl.tools at gmail.com> wrote:
> "empty type".  An empty type is either an array of empty types or a
> class type where every member is of empty type.

Note that the term "empty type" is commonly used in type theory to
denote a (or the) type with no values.  The closest thing C has would be
an empty enum when using -fstrict-enums.  (Declaring it as return type
implies [[noreturn]] or undefined behaviour.)

A type with a unique value (such as void or an empty struct) is usually
known as a unit type.

BTW, being standard layout is not sufficient (nor required afaict) for
zero-register passing of a unit type.  The requirement you need is
trivially-copyable.  Example:

	#include <map>
	#include <iostream>
	#include <type_traits>

	using namespace std;

	class EmptyInt {
		static map< const EmptyInt *, int > values;

	public:
		EmptyInt() = default;
		EmptyInt( int x ) {  values[this] = x;  }
		~EmptyInt() {  values.erase(this);  }

		operator int () const {  return values[this];  }
	};

	typeof( EmptyInt::values ) EmptyInt::values;

	EmptyInt foo() {
		return 42;
	}

	int main() {
		cout << is_standard_layout<EmptyInt>{} << endl;
		cout << foo() << endl;
		return 0;
	}

This evil contraption satisfies all POD-requirements except for not
being trivially-copyable.  On the other hand taking this example from
http://en.cppreference.com/w/cpp/concept/StandardLayoutType

	struct Q {};
	struct S : Q {};
	struct T : Q {};
	struct U : S, T {};	// not a standard-layout class

Even though U is not standard-layout, it is trivially-copyable and I see
no reason to allocate a register to pass it.

Matthijs van Duin


More information about the cfe-commits mailing list