https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64384
--- Comment #5 from daniel.c.klauer at web dot de --- I also think that COM is supposed to be usable from C and C++, but it seems that here we have an exception to this rule. Let's examine asm generated by the ms compiler for calls to GetSize(), C and C++ versions respectively: C++: ID2D1HwndRenderTarget *hwndRenderTarget; D2D1_SIZE_F size; size = hwndRenderTarget->GetSize(); Code generated by cl: lea edx, DWORD PTR $T76363[ebp] # temp var for the result push edx # hidden pointer arg [...push THIS arg and get function pointer from vtable into eax...] call eax # returns pointer to temp var in eax mov ecx, DWORD PTR [eax] # reading result from temp var, 1st member mov edx, DWORD PTR [eax+4] # 2nd member of D2D1_SIZE_F mov DWORD PTR _size$[ebp], ecx mov DWORD PTR _size$[ebp+4], edx C: ID2D1HwndRenderTarget *hwndRenderTarget; D2D1_SIZE_F size; size = hwndRenderTarget->lpVtbl->Base.GetSize( (ID2D1RenderTarget *)hwndRenderTarget); Code generated by cl: [...push THIS arg and get function pointer into ecx...] call ecx mov DWORD PTR _size$[ebp], eax # reading result from edx:eax registers mov DWORD PTR _size$[ebp+4], edx The C++ version works well; the C version crashes at the GetSize() call. They're using incompatible aggregate return mechanisms (despite stdcall), but since the d2d1.dll (which, I assume, implements this interface) will only use one of the two mechanisms, the other won't work. Obviously d2d1.dll uses the C++ version because that's what works. Assuming this is part of MS ABI and not a bug in the MS compiler, then the problem with gcc is that its aggregate return for C++ methods differs from MS ABI (though it's correct for normal C-style functions).