1

Consider the following C++ code:

struct X
{
        int a;
        int b;
};

X foobar()
{
        X x = { 1, 2 };
        return x;
}

Now assume this code is put in a shared library, which is used by third-party applications.

My question is: if I add another member at the end of X (e.g. int c), and initialize it in foobar(), will existing applications which call foobar() break? Note that this is about binary compatibility, not source compatibility.

Etienne Dechamps
  • 24,037
  • 4
  • 32
  • 31
  • How is the "new" struct going to be used? The client code needs X to be declared in a header. Which X are you going to declare? Bottom line, you don't want to do this, it's why things like COM were invented. –  Jun 08 '11 at 16:29
  • `X` is declared and defined in a header which is used to compile the application. `foobar()` is declared in a header but defined in a `.cpp` file inside the shared library. Of course, if `X` changes, the application won't be recompiled and so won't "see" that the header changed. Hence the question. – Etienne Dechamps Jun 08 '11 at 16:33
  • Short answer: Don't do it. Long answer: Why would you want to do that? What's the real situation here? – Kerrek SB Jun 08 '11 at 16:56
  • @Kerrek SB: in my particular situation that's just the simplest way to write my code. Neither the library nor the applications are written yet; I was just wondering if I could write this and still maintain binary compatibility in case `X` evolves. It seems that's not the case, so I'll just write it another way. No worries. – Etienne Dechamps Jun 08 '11 at 17:02

2 Answers2

3

It depends entirely on what your compiler chooses to do (more specifically, what the platform ABI dictates).

You can imagine that if the return value is placed on the stack, you would now be writing more onto the stack than the caller is expecting, which may result in stamping on something.

In general, you shouldn't rely on any particular behaviour. You simply must re-compile the client applications. The only realistic alternative is something like the PIMPL idiom.

Oliver Charlesworth
  • 267,707
  • 33
  • 569
  • 680
  • How can I be sure if the result value will be placed on the stack or not? – Etienne Dechamps Jun 08 '11 at 16:30
  • *you* can't which is part of the problem. – Andrew White Jun 08 '11 at 16:31
  • 1
    @e-t172: What do you mean by "sure"? The C++ standard does not cover this sort of thing, you are looking at purely implementation-defined results. You will need to know how your compiler arranges the stack (this will be defined in the compiler's ABI). In general, relying on any particular behaviour here is not a good idea. – Oliver Charlesworth Jun 08 '11 at 16:32
  • You can be reasonably sure that whatever mechanism the ABI uses to return objects of class type, it will depend on their size in some important way. Oli just gives a common example - the caller makes space available for the return value, hence if the sizes mismatch then this space will be overrun. – Steve Jessop Jun 08 '11 at 17:07
3

Since the size of X would change, yes. Arrays and such depend on sizes. You might get "lucky" and padding might allow older apps to use the newer lib but it would be pure luck.

Andrew White
  • 52,720
  • 19
  • 113
  • 137