views:

132

answers:

5

I have an abstract class in my DLL.

class Base {
  virtual char * First() = 0;
  virtual char * Second() = 0;
  virtual char * Third() = 0;
};

This dinamic library and this interface are used for a long time. There is my mistake in my code. Now I want to change this interface

class Base {
  virtual const char * First()  const = 0; 
  virtual const char * Second()       = 0;
  virtual       char * Third()  const = 0;
};

Some EXE-program uses my DLL. Will the EXE-program work without recompilation? Consider changes in each line of new interface independently.

Note: of course, EXE-program does not change functions results.

A: 

since you change your interface, you have to recompile (i think)

ufukgun
A: 

Probably won't work. Though the easiest way to know for sure is to try it and see

Glen
What about the future? I will change VS2008 to VS2010, VS2015, VS2137 somewhen.
Alexey Malistov
+1 for suggesting to try it
ChrisF
I don't think trying is the right way. It might work or it might silently trash other data.
EFraim
All bets are off for VS2015+, Microsoft might change anything, up to and including the name-mangling or the calling convention, so that it is not possible to link *any* VS2008 exe against a VS2015 dll, even compiled with identical headers. VS2010 is mostly done AFAIK, all this stuff is bound to be documented somewhere.
Steve Jessop
@Alexey if you change compilers then you'll have to recompile EVERYTHING anyway, so that's not a valid concern.
Glen
@EFraim, true, but there are 3 possible out comes of just trying it. 1, it works. 2, it silently trashed data, 3, it fails in an obvious way. Trying it will at least rule out option 3.
Glen
And at best it rules out (1) and (2), so that you "know for sure" :-)
Steve Jessop
+3  A: 

Your EXE could change result of function since it was char*. Now it is const char*. And changing const object will lead to undefined behavior according to C++ Standard 7.1.5.1/3-4:

A pointer or reference to a cv-qualified type need not actually point or refer to a cv-qualified object, but it is treated as if it does; a const-qualified access path cannot be used to modify an object even if the object referenced is a non-const object and can be modified through some other access path. [Note: cv-qualifiers are supported by the type system so that they cannot be subverted without casting (5.2.11). ]

Except that any class member declared mutable (7.1.1) can be modified, any attempt to modify a const object during its lifetime (3.8) results in undefined behavior.

Kirill V. Lyadvinsky
EXE-program does not change functions results.
Alexey Malistov
+1  A: 

It "shouldn't" work, but you never know your luck.

Because of overloading, char *First() and const char *First() const are different functions. You could have both in the same class. So any name-mangling scheme has to map them to different names, which obviously is a problem when it comes to binding.

But, these are virtual calls, and you have three functions replaced by their equivalents in the same order. I don't know any details of MSVC's vtable scheme, in particular whether the offsets are statically determined or dynamically bound. If the former, it's possible that the exe can bind against the new vtable. The function pointers might just so happen to work, because the calling convention doesn't depend on cv-qualification (that is, a const char* is returned the same way a char* is, and const this is passed the same way non-const this is).

Even if it does work, I wouldn't want to rely on it unless it's something that MS specifically addresses and guarantees.

Steve Jessop
You write "the calling convention doesn't depend on cv-qualification". That is the question. Is it right?
Alexey Malistov
It is for Win32. `this` is passed in ECX whether it's const or not, and a `char*` return is in EAX, whether it's const or not. But that alone isn't sufficient for the binding to work. As I say I don't know about MSVC's vtables, and I also don't know the Win64 calling convention (if you have a 64bit release).
Steve Jessop
Why only the fourth man understood my question? — rhetorical.
Alexey Malistov
What about case when my functions have argumnets?
Alexey Malistov
I doubt that any part of the Windows calling convention is affected by the const-ness of the parameters. If in doubt, though, you could get your disassembler out and have a look. Flip things between const and non-const, and see if it affects the code. If the compiled calling code is identical either way (and links the same symbols), then the old exe must still work because it's identical with the new one. For this version of the compiler, with these compiler options, etc, and also with any other version/options which MS says is binary-compatible.
Steve Jessop
A: 

I don't think this will work. Changing the interface of a DLL usually requires the executable that links to it to be recompiled.

In addition, you will likely need to make changes to the code in the executable, as you have changed the function signatures.

Lastly, if you are going to update/append an interface, you would be best to subclass the original interface. This will prevent any existing code from breaking.

Steven