C++ Templates and symbols not defined in .o files

Wesley Smith wesley.hoke@gmail.com
Sat Sep 18 20:10:00 GMT 2010


I'm trying to figure out a really hairy issue with C++ templates and
symbols in GCC 4.4.3:

I have a class templated on another class (only showing one of the
many functions)

template <typename T>
class Glue {
public:

static bool usr_attr_is_prototype(lua_State *L);
};

and then defined in the same .h

template <typename T> bool Glue<T>::usr_attr_is_prototype(lua_State *L) {
	return lua_istable(L, 1) == 1;
}

The problem is that when I go to use it in a .cpp file, the symbol for
this function is U (undefined) instead of W (weak) as it should be.
For example, I have a couple of .cpp files that use the exact same
code, just changing the class T the template is based on.  In all but
1 of the .o files resulting, the symbol is W.  What's strange is that
I'm compiling these files with exactly the same flags.


g++ -g -fmessage-length=0 -pipe -fPIC -Wno-trigraphs -Wreturn-type
-Wunused-variable -D__LINUX__ -O0
-I/home/wesleysmith/Documents/new_luaav/trunk/buildtool/../modules/opengl/include
-I/home/wesleysmith/Documents/new_luaav/trunk/buildtool/../modules/opengl/include/graphics
-I/home/wesleysmith/Documents/new_luaav/trunk/buildtool/../modules/opengl/include/math
-I/home/wesleysmith/Documents/new_luaav/trunk/buildtool/../modules/opengl/include/protocol
-I/home/wesleysmith/Documents/new_luaav/trunk/buildtool/../modules/opengl/include/types
-I/home/wesleysmith/Documents/new_luaav/trunk/buildtool/../modules/opengl/src/glew
-I/home/wesleysmith/Documents/new_luaav/trunk/buildtool/../modules/opengl/src/glew/GL
-I/home/wesleysmith/Documents/new_luaav/trunk/buildtool/../dev/include
-I/usr/include/lua5.1
-I/home/wesleysmith/Documents/new_luaav/trunk/buildtool/../dev_linux/include
-o /home/wesleysmith/Documents/new_luaav/trunk/buildtool/../modules/opengl/build/Debug/lua_opengl_shader.o
-c /home/wesleysmith/Documents/new_luaav/trunk/buildtool/../modules/opengl/src/lua_opengl_shader.cpp

g++ -g -fmessage-length=0 -pipe -fPIC -Wno-trigraphs -Wreturn-type
-Wunused-variable -D__LINUX__ -O0
-I/home/wesleysmith/Documents/new_luaav/trunk/buildtool/../modules/opengl/include
-I/home/wesleysmith/Documents/new_luaav/trunk/buildtool/../modules/opengl/include/graphics
-I/home/wesleysmith/Documents/new_luaav/trunk/buildtool/../modules/opengl/include/math
-I/home/wesleysmith/Documents/new_luaav/trunk/buildtool/../modules/opengl/include/protocol
-I/home/wesleysmith/Documents/new_luaav/trunk/buildtool/../modules/opengl/include/types
-I/home/wesleysmith/Documents/new_luaav/trunk/buildtool/../modules/opengl/src/glew
-I/home/wesleysmith/Documents/new_luaav/trunk/buildtool/../modules/opengl/src/glew/GL
-I/home/wesleysmith/Documents/new_luaav/trunk/buildtool/../dev/include
-I/usr/include/lua5.1
-I/home/wesleysmith/Documents/new_luaav/trunk/buildtool/../dev_linux/include
-o /home/wesleysmith/Documents/new_luaav/trunk/buildtool/../modules/opengl/build/Debug/lua_opengl_slab.o
-c /home/wesleysmith/Documents/new_luaav/trunk/buildtool/../modules/opengl/src/lua_opengl_slab.cpp

wesleysmith@ubuntu:~/Documents/new_luaav/trunk/modules/opengl/build/Debug$
nm lua_opengl_shader.o | grep usr_attr
00000000 W _ZN4GlueIN2al3gfx6ShaderEE11usr_attr_mtEP9lua_StateP8luaL_RegS7_S7_
00000000 W _ZN4GlueIN2al3gfx6ShaderEE13usr_attr_pushEP9lua_State
00000000 W _ZN4GlueIN2al3gfx6ShaderEE14usr_attr_indexEP9lua_StatePS2_
00000000 W _ZN4GlueIN2al3gfx6ShaderEE17usr_attr_newindexEP9lua_StatePS2_
00000000 W _ZN4GlueIN2al3gfx6ShaderEE18usr_attr_prototypeEP9lua_State
00000000 W _ZN4GlueIN2al3gfx6ShaderEE21usr_attr_is_prototypeEP9lua_State

wesleysmith@ubuntu:~/Documents/new_luaav/trunk/modules/opengl/build/Debug$
nm lua_opengl_slab.o | grep usr_attr
00000000 W _ZN4GlueIN2al3gfx4SlabEE11usr_attr_mtEP9lua_StateP8luaL_RegS7_S7_
         U _ZN4GlueIN2al3gfx4SlabEE13usr_attr_pushEP9lua_State
00000000 W _ZN4GlueIN2al3gfx4SlabEE14usr_attr_indexEP9lua_StatePS2_
00000000 W _ZN4GlueIN2al3gfx4SlabEE17usr_attr_newindexEP9lua_StatePS2_
         U _ZN4GlueIN2al3gfx4SlabEE18usr_attr_prototypeEP9lua_State
         U _ZN4GlueIN2al3gfx4SlabEE21usr_attr_is_prototypeEP9lua_State




The function is used like this:

template<> Slab * Glue<Slab>::usr_new(lua_State * L) {
	string ctx;
	
	if(
		Glue<Slab>::usr_attr_is_prototype(L) &&  //
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
		lua::checkfield<const char *>(L, 1, "ctx")
	) {
		ctx.assign(lua::tofield<const char *>(L, 1, "ctx"));
		setup_prototype_params(L);
	}
	else if(lua::is<const char *>(L, 1)) {
		ctx.assign(lua::to<const char *>(L, 1));
	}
	else {
		luaL_error(L, "Slab(): missing context name");
	}

	GraphicsBackend *backend = lua_opengl_get_backend(ctx.c_str());
	Slab *slab = new Slab(backend);
	lua_opengl_register(ctx.c_str(), slab);
	return slab;
}


gcc -v

Target: i486-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu
4.4.3-4ubuntu5'
--with-bugurl=file:///usr/share/doc/gcc-4.4/README.Bugs
--enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr
--enable-shared --enable-multiarch --enable-linker-build-id
--with-system-zlib --libexecdir=/usr/lib --without-included-gettext
--enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.4
--program-suffix=-4.4 --enable-nls --enable-clocale=gnu
--enable-libstdcxx-debug --enable-plugin --enable-objc-gc
--enable-targets=all --disable-werror --with-arch-32=i486
--with-tune=generic --enable-checking=release --build=i486-linux-gnu
--host=i486-linux-gnu --target=i486-linux-gnu
Thread model: posix
gcc version 4.4.3 (Ubuntu 4.4.3-4ubuntu5)




I'm totally baffled as to how to debug this.  Is there any reason
_ZN4GlueIN2al3gfx4SlabEE21usr_attr_is_prototypeEP9lua_State should be
undefined?

thanks,
wes



More information about the Gcc-help mailing list