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