Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Safe cross-compiler ABI in C++?

Tags:

c++

In the cpp core guidelines, there is a (partially incomplete) statement:

I.26: If you want a cross-compiler ABI, use a C-style subset

Reason

Different compilers implement different binary layouts for classes, exception handling, function names, and other implementation details.

Exception

You can carefully craft an interface using a few carefully selected higher-level C++ types. See ???.

A good example of a cross-compiler ABI would be a plugin system. Let's say I want this to be as C++-friendly as possible.

The interface:

class Plugin
{
public:
    virtual ~Plugin() {}

    enum class Type {A, B, C};
    virtual Plugin::Type getType() const = 0;

    virtual void doWork() = 0;
};

// C-style for the main plugin entry function
typedef Plugin* (*PluginCreateCallback)();
typedef void (*PluginDestroyCallback)(Plugin*);
extern "C" void pluginMain(PluginCreateCallback* createCb, PluginDestroyCallback* destroyCb);

A plugin implementation (compiled with compiler#1) might look like:

class MyPlugin: public Plugin
{
    Plugin::Type getType() const override {return Plugin::Type::A;}
    void doWork() {...}
};

Plugin* myCreateCb()
{
    return new MyPlugin();
}

void myDestroyCb(Plugin* plugin)
{
    delete plugin;
}

extern "C" void pluginMain(PluginCreateCallback* createCb, PluginDestroyCallback* destroyCb)
{
    *createCb = &myCreateCb;
    *destroyCb = &myDestroyCb;
}

The application implementation (compiled with compiler#2) would contain something like:

handle->pluginMain(&createCb, &destroyCb);
Plugin* plugin = createCb();
plugin->doWork();
destroyCb(plugin);

Questions:

  • is it safe to use classes like Plugin in a cross-compiler environment? (will it be represented the same in memory?)
  • will extending the Plugin::Type enum affect how the Plugin class is represented?
  • more generally, what would be those "carefully selected higher-level C++ types"?

Update:

In the "API design for C++" book by Martin Reddy, chapter 12, the exact scenario of using plugin interfaces seems to be specified:

Implementing virtual methods of an abstract base class can insulate a plugin from ABI problems because a virtual method call is usually represented as an index into a class’s vtable. Theoretically, the vtable format can differ between compilers, but in practice this tends not to happen.

From this, I understand that using abstract classes is generally safe between compilers, but definitely not guaranteed by the standard.

like image 977
Claudiu Avatar asked Oct 26 '25 02:10

Claudiu


1 Answers

I opened an issue on Github to get examples of such exceptions and Herb Sutter's answer was:

Editors call: We don't have a reference to point to, so we agree we should just remove the Exception. Thanks!

This Exception paragraph has now been removed from the guildelines.

like image 162
Holt Avatar answered Oct 28 '25 16:10

Holt



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!