C++ Logo

std-proposals

Advanced search

Re: [std-proposals] Standard support for different ABI's for class vtables

From: Andre Kostur <andre_at_[hidden]>
Date: Fri, 30 May 2025 05:53:39 -0700
I doubt it. The Standard doesn’t mandate a “vtable pointer” either.
Neither does it talk about any of the other ABI things (other than linkage,
and even then doesn’t say much about that either). This would seem to be
entirely a discussion for the compiler vendors.

On Fri, May 30, 2025 at 5:32 AM Frederick Virchanza Gotham via
Std-Proposals <std-proposals_at_[hidden]> wrote:

> On an x86_64 computer, we can build a DLL file using Visual Studio,
> and then link it with an executable file built with GNU g++. We just
> need to make sure that the same calling convention is used when the
> executable invokes functions found inside the DLL.
>
> But if the DLL file returns a pointer to an abstract base class
> object, something like:
>
> extern "C" IExaminer *CreateNewExaminer(void) noexcept;
>
> then we'll have a problem when we try to invoke methods on the
> returned object because the Microsoft vtable might be different to
> what the GNU g++ executable is expecting. The worse scenario will be
> when 'IExaminer' inherits from a non-polymorphic base class, such as:
>
> struct Base {
> int n;
> };
>
> class IExaminer : public Base { . . . };
>
> Because when we have a pointer to an "IExaminer" object, the Microsoft
> compiler will put the vtable pointer at address [base + 0x04], but the
> GNU compiler will put the vtable pointer at address [base + 0x00].
>
> I'm just wondering if there's any possibility -- it's probably
> unlikely -- but could we put something in the Standard to try
> accommodate this?
>
> One workable solution not requiring any change to the Standard is to
> create a second project in Visual Studio, and to put in it a
> standalone function for each of IExaminer's methods:
>
> int IExaminer_GetStatus(IExaminer *const p) { return p->GetStatus(); }
>
> void IExaminer_SetAvailability(IExaminer *const p, bool const b) {
> p->SetAvailability(b); }
>
> So then the GNU g++ executable would link with this second project and
> use these stub functions to interact with the "IExaminer" object. A
> tool could be written to automate this process of creating the second
> project (maybe it's been done already?).
>
> Another solution, and this might be a bit far-fetched, might be to
> standardise something that works along the following lines . . . You'd
> have the following in your GNU g++ executable C++ source file:
>
> IExaminer *const p = CreateNewExaminer();
>
> and on the next line you would do:
>
> typedef std::abi< std::abi::Microsoft, IExaminer > IExaminer_Microsoft;
> IExaminer_Microsoft *const pm = std::abi_wrap<IExaminer_Microsoft>(p);
> int const status = pm->GetStatus();
>
> The function "std::abi_wrap" would return an object that you can use
> exactly like an 'IExaminer' in your GNU executable, and internally it
> would be something like:
>
> class IExaminer_Microsoft {
> public:
> typedef IExaminer type;
> IExaminer *p;
> int GetStatus(void) // Note that this is not virtual
> {
> // Adjust the vtable pointer for Microsoft:
> char unsigned const *const pobj = static_cast<char
> unsigned*>(static_cast<void*>(p));
> typedef int (*FuncPtr)(IExaminer*);
> FuncPtr *const vtable = static_cast<FuncPtr*>(
> static_cast<void*>( pobj + 4 ) );
> return vtable[3]( this->p ); // GetStatus is the 4th
> entry in the vtable
> }
> };
>
> In order for the GNU compiler to be able to generate the class
> IExaminer_Microsoft, it would need either one of two things:
> (1) The GNU compiler would have to be programmed with how
> Microsoft lays out classes -- including in cases of multiple virtual
> inheritance, and would have to map it all across to how GNU does
> things. I could see this code getting very complicated (although maybe
> the latest version of ChatGPT/CoPilot or whatever could take a good
> stab at it).
> (2) The Microsoft compiler could be augmented to output such a
> class. So you would invoke 'cl.exe' something like:
>
> cl.exe /input_file:IExaminer.hpp /input_class:IExaminer
> /out_abi_class:IExaminer_Microsoft.hpp
>
> The Standard library could provide templates and classes such as
> "std::abi" and "std::abit_wrap", and then it would be up to the
> compiler implementors to add a new compiler option to output a class
> like I've shown above.
>
> Before writing this email I had considered that this might be way
> outside the scope of the Standard -- which doesn't by the way even
> seem to acknowledge the existence of shared libraries -- but maybe
> some of this could be standardised, such as the names and use of the
> classes and functions like "std::abi" and "std::abi_wrap"?
>
> It would be really cool if C++29 compilers were expected to have a
> feature whereby they would output an "ABI helper class" for any class
> you specify, like the helper class I've shown about that finds the
> vtable and manually invokes the right method. It would mean that
> different compilers with different ABI's could work together with each
> others' binaries more easily.
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>

Received on 2025-05-30 12:53:51