Handling SRet on Windows x86...

COM is not a language extension.

It is a codification of a fairly obvious but not guaranteed C++ ABI/objectmodel decision.

Specifically given C++:

class Foo
{
public:
virtual void Abc() = 0;
virtual void Def() = 0;
};

Foo* foo;
foo->Abc();

what is the ABI in terms of C?

Note well the “virtual” and “=0”. They are important.

COM declares that is this (except for old CFM Macintosh PowerPC?):

struct Foo;
typedef struct Foo Foo;

struct FooFunctions
{
void (Abc)(Foo);
void (Def)(Foo);
};

struct Foo
{
FooFunctions const * Functions;
};

Foo* foo;
foo->Functions->Abc(foo);

There are other possibilities, but is what COM says.

WinRT is seemingly merely a way to encode .h files in a binary format,
that then describe things like the above.

There is a string library, which you can have the compiler deal with or not.
There is COM’s IUnknown, ditto.

That is really about it as I understand.

What is “system compiler”?
The OS is likely compiled with multiple compilers.
It certainly can run binaries compiled with multiple compilers.
What is in question, I guess, is what is the ABI.
The C ABI, and the C++ ABI.
C ABIs are generally smaller more obvious but not completely automatic things.
Struct passing and return being one of the less obvious aspects.

Ideally there’d be documentation and agreement on the C ABI.

C++ ABIs include lots of details – name mangling, exception handling…
That is much more difficult to deal with.
Name mangling in Visual C++ has changed through the years.
For example, years ago, template parameters were not encoded in function names, so multiple instances of this:

template int Foo() {return a;}
or this:
template T* New() {return new T;}

got the same name.

Foo<1>();
Foo<2>();
New();
New();

and the linker would just pick one…oops…

Fixing that required an ABI change.
So it is a good thing the original name mangling wasn’t documented and copied!
(Better still would be to get it right the first time…)

  • Jay