7
votes

Assume I have a library that declares a function returning const type:

class Foo { ... };
const Foo makeFoo();

Now I want to remove const from makeFoo() return type (See my previous question). I can remove const both from the header and the cpp file, rebuild the library, and link my code to the new library. However, I also have old code that is dynamically linked to this library, and I want it to continue to work with the new version of the library.

So, first question, does removing const from return type break ABI?

Second question, the actual code is quite different: it is a template class that has a static member function and that is later explicitly instantiated:

// fooMaker.h
template<class Foo>
class FooMaker {
public:
    static const Foo make();
};

// fooMaker.cpp
template<class Foo>
const Foo FooMaker<Foo>::make() { ... }

template class FooMaker<Foo1>;
template class FooMaker<Foo2>;

Is it changing anything?

If that's important, I'm using g++ under linux.

1
@ZunTzu, in fact I see two possible problems: name mangling and possible UB due to treatment of a non-const object as const (imagine I was adding const instead of removing; then this will clearly lead to UB similarly to my previous question). For the former, I am more interested in a practical answer for g++/linux, as if g++ changes name mangling scheme, then this will not be the only problem. For the latter, I am more interested in a legal one answer, as it is not good to leave some UB or the like behind.Petr
Since the return type is not part of the mangled function name, there is no effect on name mangling.Walter
Practical answer : g++ name mangling apparently does not use the return type (see here).ZunTzu
Legal answer : last time I checked C++ had no standard ABI.ZunTzu
On the legal side: If the definition differs from the declaration in this way you have an ODR violation. Practically I doubt it matters.Alan Stokes

1 Answers

1
votes

The following guidelines on what affects the ABI suggest that the answer is yes, it does break ABI compatibility:

You cannot

...

For existing functions of any type:

  • changing the return type in any way

Since you are changing the return type from const Foo to Foo I would say this falls foul.