Templates + Inheritance problem
Hi, I've found strange behavior, possibly a bug, but more likely a problem with my understanding. Here's the code: template class Foo { public: void Baz() {} }; template class Bar : public Foo { public: void Bum() { Baz(); } }; (I know it doesn't make much sense, I reduced the problem down to simplest terms). I get an error compiling: [EMAIL PROTECTED]:~/tmp$ g++ -c Foo.C Foo.C: In member function 'void Bar::Bum()': Foo.C:11: error: there are no arguments to 'Baz' that depend on a template parameter, so a declaration of 'Baz' must be available Foo.C:11: error: (if you use '-fpermissive', G++ will accept your code, but allowing the use of an undeclared name is deprecated) Can someone tell me why Baz is undeclared here? version: [EMAIL PROTECTED]:~/tmp$ g++ -v Using built-in specs. Target: i486-linux-gnu Configured with: ../src/configure -v --enable-languages=c,c++,fortran,objc,obj-c++,treelang --prefix=/usr --enable-shared --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --enable-nls --program-suffix=-4.1 --enable-__cxa_atexit --enable-clocale=gnu --enable-libstdcxx-debug --enable-mpfr --enable-checking=release i486-linux-gnu Thread model: posix gcc version 4.1.2 20060928 (prerelease) (Ubuntu 4.1.1-13ubuntu5) Thanks, j -- John Gateley <[EMAIL PROTECTED]>
cannot pass objects of non-POD type
Hi. I'm having trouble with the dreaded: cannot pass objects of non-POD type 'sometype' through '...' message. Here's a brief example: class String { public: void SetData(char *NewData) { m_Data = NewData; } char *m_Data; }; int Bar(char *s, va_list ArgList) { printf("String: %s\n", s); printf("Arg2: %s\n", va_arg(ArgList, char *)); } int Foo(char *s, ...) { va_list ArgList; va_start(ArgList, s); int Result = Bar(s, ArgList); va_end(ArgList); return Result; } int main(int argc, char **argv) { String MyString; MyString.SetData("ghi"); Foo("abc", MyString); } This works because String::m_Data is public. If I only change it so that m_Data is private: class String { public: void SetData(char *NewData) { m_Data = NewData; } private: char *m_Data; }; The program now gives the dreaded warning, and crashes on execution. Given that I know what I am doing (I am using the fact that String has a single data member which is a pointer to character to copy just that pointer to character to the argument list), is there any way to accomplish this? Is the crash a "real" crash, or is it a crash generated by the compiler just to enforce passing non-PODness? It definitely seems like the latter. The situation is this: I have a lot of code that uses a string class which takes advantage of the pun: the string class has only the one data member, which means you can do things like printf("%s", obj) and have the right thing happen (using a different compiler, of course). Is there any way to use this useful pun with g++? Thanks, j -- John Gateley <[EMAIL PROTECTED]>
Re: cannot pass objects of non-POD type
On Wed, 24 Oct 2007 12:03:38 -0700 "Andrew Pinski" <[EMAIL PROTECTED]> wrote: > On 10/24/07, John Gateley <[EMAIL PROTECTED]> wrote: > > The situation is this: I have a lot of code that uses a string class > > which takes advantage of the pun: the string class has only the > > one data member, which means you can do things like printf("%s", obj) > > and have the right thing happen (using a different compiler, of course). > > Is there any way to use this useful pun with g++? > > This is way undefined code really. The class is a non POD since you > have a private member. And the C++ standard says it is undefined what > happens when you pass a non-POD for a varable arguments function (the > reasoning is due to virtual functions and knowning the full size of > the struct). > > Also using %s with anything but a char* is undefined behavior anyways > (even if it is a struct that only contains a char* since the ABI could > say they are passed differently). I don't think it is undefined code. The class has no virtual functions, and the variable argument function doesn't need to know the full size of the struct, since it is not using it as a String object, it is using it as a char * pointer (which is what gets passed). I'm not familiar with "ABI". But perhaps this has something to do with my other question: is the illegal instruction that gets executed a "real" illegal instruction, caused by g++ doing something different that I expected with the String object as an argument? Or is the illegal instruction just a "place marker" that is generated because I passed a non-POD as an argument? Thanks for your reply... j -- John Gateley <[EMAIL PROTECTED]>
Re: cannot pass objects of non-POD type
On Wed, 24 Oct 2007 12:37:50 -0700 "Andrew Pinski" <[EMAIL PROTECTED]> wrote: > What exactly does that mean? Do we pass it as a String or as a "b"? > This is the reason why non-POD through variable arguments is > undefined. True, but this relies on "b" being a virtual class. The case I had was very simple, purposely so. While for complex objects, passing them could be a disaster, in this case it is a simple clean construction that is useful. I'm working on porting approximately a million lines of code (which also must remain working on the original platform), and the pun (using a struct/class containing a single data member which is a pointer to char, and not containing a vtab) is pervasive throughout. It would be really nice if I didn't have to do thousands of changes like: Format("%s", Object) becoming Format("%s", (char *)Object)); Thanks, j -- John Gateley <[EMAIL PROTECTED]>