11

Assuming the following header file corresponding to, for example, a shared library. The exported function takes a pointer to a custom structure defined in this header:

// lib.h

typedef struct {
  char c;
  double d;
  int i;
} A;

DLL_EXPORT void f(A* p);

If the shared library is built using one compiler and then is used from C code built with another compiler it might not work because of a different memory alignment, as Memory alignment in C-structs suggests. So, is there a way to make my structure definition portable across different compilers on the same platform?

I am interested specifically in Windows platform (apparently it does not have a well-defined ABI), though would be curious to learn about other platforms as well.

Community
  • 1
  • 1
Roman L
  • 3,006
  • 25
  • 37
  • 3
    No, unless someone guaranteed you that. –  Apr 24 '12 at 12:50
  • 3
    No duplicate. At least not of the question selected. This one can stand on its own. – San Jacinto Apr 24 '12 at 13:05
  • 1
    Is any question containing words "struct alignment" automatically a duplicate of that other question even when it has nothing to do with it?.. – Roman L Apr 24 '12 at 14:28
  • The proposed duplicate actually answer the question *"is it guaranteed that the structure memory alignment will be the same?"* just fine. It's not guaranteed because the c standard lets each compiler make it's own choices. If the intended primary question here is *"how do I make sure that my structure definition is portable across different compilers on the same platform?"* it should be made more prominent. And you should try reading the documentation for the compilers in question. – dmckee --- ex-moderator kitten Apr 24 '12 at 21:30
  • @dmckee, thanks for your input, I reworded the question a bit. – Roman L Apr 25 '12 at 13:58

3 Answers3

13

TL;DR in practice you should be fine.

The C standard does not define this but a platform ABI generally does. That is, for a given CPU architecture and operating system, there can be a definition for how C maps to assembly that allows different compilers to interoperate.

Struct alignment isn't the only thing that a platform ABI has to define, you also have function calling conventions and stuff like that.

C++ makes it even more complex and the ABI has to specify vtables, exceptions, name mangling, etc.

On Windows I think there are multiple C++ ABIs depending on compiler but C is mostly compatible across compilers. I could be wrong, not a Windows expert.

Some links:

Anyway the bottom line is that you're looking for your guarantee in the platform/compiler ABI spec, not the C standard.

Community
  • 1
  • 1
Havoc P
  • 8,365
  • 1
  • 31
  • 46
  • Thanks for your efforts, though my question does not concern C++ at all. I know about ABI, that's also why I marked the question Windows-specific as I never heard of ABI specifications on Windows. – Roman L Apr 24 '12 at 14:26
  • @7vies: C has an ABI as well (think of the different calling conventions, cdecl, stdcall, fastcall). It's just that for C the different compilers are usually the same (at least for the 'normal' calling conventions), if for no other reason than to match what the OS expects for system calls. With C++ the different compilers often *don't* agree on the same API, especially for external names. – Michael Burr Apr 24 '12 at 14:42
  • @MichaelBurr, as a side note, wikipedia says these are _x86_ conventions, are they used on other architectures as well? I am aware of the C++ issues, that is why I am asking how to make it work in pure C. Calling conventions do help to define a portable interface, but do not solve my problem with structure alignment. – Roman L Apr 25 '12 at 13:53
  • @7vies: every platform has its own calling conventions/ABIs (though they may influence one another; the Itanium ABI seems to have influenced several 64-bit platform ABIs). I just listed the x86 ones as examples of how even C has an ABI. I think Havoc's answer is pretty much what you have - there's no promise from the C standard, but platform requirements will make it so that in practice struct alignment will be the same across compilers (POD strcuts for C++) as long as you don't mess with oddball types (like maybe `long long double`) or misuse options that affect alignment. – Michael Burr Apr 25 '12 at 20:34
4

The only way to know for sure is to consult the documentation of the compilers in question. However, it is usually the case that C struct layout (except, as you say, for bitfields) is defined by an ABI description for the environment you're using, and C compilers will tend to follow the native ABI.

caf
  • 233,326
  • 40
  • 323
  • 462
1

Not only that it is not guarantied, but even if you use the same compiler there might be differences due to different compiler switches used in the build, or if you use different versions of the same compiler and same switches (happened in an embedded compiler I worked on).

You need to make make sure the structs are represented exactly the same, use switches, #pragmas, whatever the compilers gives you.

My advice - to stay way from this altogether. Pass your arguments in the function, not wrapped within a struct.

And even in this simple form, if you deal with two compilers, it's not trivial. You need to make sure that an int takes the same number of bytes, for example. Also calling conevntion - arguments order - from left to right or from right to left - can differ between compiler.

Israel Unterman
  • 13,158
  • 4
  • 28
  • 35