public inbox for gcc-help@gcc.gnu.org
 help / color / mirror / Atom feed
* Runtime warning: Symbol [vtable] has different size in shared object, consider relinking
@ 2014-01-07 23:06 Tyler Cardon
  2014-01-08  8:57 ` Jonathan Wakely
  0 siblings, 1 reply; 2+ messages in thread
From: Tyler Cardon @ 2014-01-07 23:06 UTC (permalink / raw)
  To: gcc-help

This warning is given at run-time:

./test: Symbol `_ZTV5CTest' has different size in shared object, consider
re-linking

objdump -s test | grep _ZTV5CTest
10: 08049b30    20 OBJECT  WEAK   DEFAULT   25 _ZTV5CTest
86: 08049b30    20 OBJECT  WEAK   DEFAULT   25 _ZTV5CTest

nm -C test | grep 08049b30
08049b30 V vtable for CTest

The executable, test, has a class that inherits from a base class defined in
libtest_base_class.so.

Does this mean that adding virtual method declarations (even without
changing virtual method order) breaks the base class library's abi?  The
program appears to run normally.  Also, this warning goes away after making
the base class abstract (i.e. repeating test with TEST_ABSTRACT
uncommented).

Compiler: GCC 3.4.0
Ran on Linux systems: Centos 6.4, Debian 3.1
Test case: 
built libtest_base_class.so with #define BUILD_EXPANDED commented out.
built test linking against libtest_base_class.so
rebuilt libtest_base_class.so with #define BUILD_EXPANDED uncommented.
ran test linking with the new libtest_base_class.so

Result:
./test: Symbol `_ZTV5CTest' has different size in shared object, consider
re-linking
Doing something with 0 and 0
0!
Doing something totally new...
2
Will this really work...
0
Seems to be working...
2
Yeah, this must be working...
1
Woot!...
42

test_base_class.h
-----------------
#ifndef TEST_BASE_CLASS_H
#define TEST_BASE_CLASS_H

#ifdef TEST_MAIN
	#define TEST_API		__attribute__((visibility("default")))
	#define TEST_LOCAL	__attribute__((visibility("hidden")))
#else
	#define TEST_API
	#define TEST_LOCAL
#endif

//#define BUILD_EXPANDED
#ifdef BUILD_EXPANDED 
	#define TEST_DISPATCH
#endif 

#define TEST_ABSTRACT

class TEST_API CTest
{

public:
	CTest();
	virtual ~CTest() {};

protected:

#ifdef TEST_ABSTRACT
	virtual int DoSomething(int x, int y);
#endif

#ifdef BUILD_EXPANDED

	virtual int DoSomethingTotallyNew(int x, int y);
	virtual int WillThisReallyWork(int x, int y);
	virtual int SeemsToBeWorking(int x, int y);
	virtual int MustReallyBeWorking(int x, int y);
	virtual int Woot(int x, int y);

	#ifdef TEST_DISPATCH
		void RunTimeDispatch();
	#endif
#endif

	TEST_LOCAL int NotExported(int x, int y);

#ifdef BUILD_EXPANDED

//---------------------------------------------------------------------------
	// Added after child build
	// 
private:
#pragma GCC visibility push(hidden)
	int m_nNewParam;
	int NewFunction(int x, int y);
#pragma GCC visibility pop
#endif

};

#endif
-------------------

test_base_class.cpp
-------------------

#define TEST_MAIN
#include "test_base_class.h"

//------------------------------------------------------------------------------
// Before child build
// 
#ifndef BUILD_EXPANDED
CTest::CTest()
{
	;
}

#endif

int CTest::NotExported(int x, int y)
{
	return (x - y);
}

int CTest::DoSomething(int x, int y)
{
	return (x - y);
}

#ifdef BUILD_EXPANDED

//------------------------------------------------------------------------------
// After child build
// 
#include "stdio.h"
int CTest::NewFunction(int x, int y)
{
	return (x + y + m_nNewParam);
}

CTest::CTest()
{
	int a = 1;
	int b = 2;
	int x = 0, y = 0;
	m_nNewParam = 5;
	printf("Doing something with %d and %d\n", x, y);
	printf("%d!\n", DoSomething(x, y));
	printf("Doing something totally new...\n");
	printf("%d\n", DoSomethingTotallyNew(a,b));
	printf("Will this really work...\n");
	printf("%d\n", WillThisReallyWork(a,b));
	printf("Seems to be working...\n");
	printf("%d\n", SeemsToBeWorking(a,b));
	printf("Yeah, this must be working...\n");
	printf("%d\n", MustReallyBeWorking(a,b));
	printf("Woot!...\n");
	printf("%d\n", Woot(a,b));
}

int CTest::DoSomethingTotallyNew(int x, int y)
{
	return (x * y);
}
int CTest::WillThisReallyWork(int x, int y)
{
	return (x / y);
}

int CTest::SeemsToBeWorking(int x, int y)
{
	return (y / x);
}

int CTest::MustReallyBeWorking(int x, int y)
{
	return (y - x);
}

int CTest::Woot(int x, int y)
{
	return (42);
}
#endif
-----------------

test_child_class.h
-----------------
#ifndef TEST_CHILD_CLASS_H
#define TEST_CHILD_CLASS_H

#include "test_base_class.h"

#endif

test.cpp
--------
#include "test_child_class.h"

class CTestChild : public CTest
{

public:

	CTestChild() {};
	virtual ~CTestChild() {};

protected:

#ifdef TEST_ABSTRACT
	virtual int MustOverride(int x, int y) { return (x + y);}
#endif

};

int main ()
{
	CTestChild* pcTest = new CTestChild;

	delete pcTest;

	return 0;
}
-------------



--
View this message in context: http://gcc.1065356.n5.nabble.com/Runtime-warning-Symbol-vtable-has-different-size-in-shared-object-consider-relinking-tp1000550.html
Sent from the gcc - Help mailing list archive at Nabble.com.

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: Runtime warning: Symbol [vtable] has different size in shared object, consider relinking
  2014-01-07 23:06 Runtime warning: Symbol [vtable] has different size in shared object, consider relinking Tyler Cardon
@ 2014-01-08  8:57 ` Jonathan Wakely
  0 siblings, 0 replies; 2+ messages in thread
From: Jonathan Wakely @ 2014-01-08  8:57 UTC (permalink / raw)
  To: Tyler Cardon; +Cc: gcc-help

On Jan 7, 2014 11:06 PM, "Tyler Cardon" wrote:
>
> Does this mean that adding virtual method declarations (even without
> changing virtual method order) breaks the base class library's abi?

It is a violation of the C++ One Definition Rule, so undefined behaviour.

It will not behave correctly if you have a class that has CTest as a
(direct or indirect) base class and adds new virtual functions to the
vtable, because the new functions will be expected to appear in
different slots in the vtable depending on which version of the base
class has been seen.

You might find http://techbase.kde.org/Policies/Binary_Compatibility_Issues_With_C++
useful.

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2014-01-08  8:57 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-01-07 23:06 Runtime warning: Symbol [vtable] has different size in shared object, consider relinking Tyler Cardon
2014-01-08  8:57 ` Jonathan Wakely

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).