Templates + Inheritance problem

2007-07-19 Thread John Gateley
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

2007-10-24 Thread John Gateley
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

2007-10-24 Thread John Gateley
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

2007-10-24 Thread John Gateley
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]>