Oleg Goldshmidt wrote:

Shachar Shemesh <[EMAIL PROTECTED]> writes:



I'm encountering a strange problem, and would like to hear the list's
ideas on why that would be. The following C++ program:



#include <stdarg.h>

class test {
public:
   virtual ~test();
};

void func( const test &param, ... )
{
va_list arg;
va_start( arg, param );
}


When trying to compile, I get the following:



test.cc: In function `void func(const test&, ...)':
test.cc:11: warning: cannot pass objects of non-POD type `const
class test'


through `...'; call will abort at runtime
test.cc:11: warning: second parameter of `va_start' not last named
argument


Researching the internet reveals that POD means "Plain Old Data",
i.e. something that can be copied bit by bit. Obviously, test is not
POD. What I don't understand is why complain about va_start. va_start
only needs test in order to know where the first non-specified
argument is. I could understand if it complained about "va_arg(arg,
const test &)", but here param is just a place holder, nothing
more. All it va_start needs to know about it is its size.

Even stranger is the second warning. If "param" is not the last named
argument, what is?



The problem is that you cannot have a last parameter that is a
reference.


Try changing it to "func( test param, ...)" (i.e. - copy constructor). It changes nothing. I'm afraid the entire explanation is plain wrong.

E.g. a trivial google finds

http://www.ishiboo.com/~nirva/c++/stl-ref/stdarg.html

that says

#define va_start(va_list ap, last-par) <void expression>
The macro stores initial context information in the object
designated by ap. last-par is the name of the last parameter you
declare. For example, last-par is b for the function declared as
int f(int a, int b, ...). The last parameter must not have
register storage class, and it must have a type that is not
changed by the translator. It cannot have:


Except:
1. It is really not authorative.
2. It sounds really strange. With an explicitly types function (and all parameters up to the last one are), all the above are well defined (even extremely well defined).


* an array type


Usually passed as pointer (4 bytes on 32bit platforms).

* a function type


Same as above.

* type float


float - 4 bytes. double - 8 bytes.

* any integer type that changes when promoted


But it's not being promoted, is it?

* a reference type [C++ only]


Pointer. See 1.

It is not authoritative, but IIRC all the above cases officially
result in undefined behaviour. This means that as strange as the
warning is g++ has the right to issue it. ;-)


Let's get one thing clear. NOTHING results in undefined behavior. If anything resulted in undefined behavior, it would have been impossible to pass it between caller and callee. What you do have is a loss of information about the type. You only get that for non explicitly defined type - i.e. - types passed as part of the ellipsis. For that reason you perform automatic promotion, and for that reason you cannot use certain types FOR ACTUAL "..." PARAMETERS.

If you read the error message, you will see that this is precisely what it complains about, in direct contradiction to what I actually did.

In order to further prove that this is a compiler bug:
1. It warns that the actual program will abort. Actual program runs fine, and does exactly what you would expect it to do.
2. Neither g++-3.4 nor Visual Studio see any problem with this construct. g++-3.3 and g++-2.95 complain, and 3.3 even gives doomsday warnings that this will crash and burn, but in reality everything works great.


Try passing a pointer to test?


Yes, with the pointer the warning goes away. I still believe this is the wrong fix.

         Shachar

--
Shachar Shemesh
Lingnu Open Source Consulting ltd.
Have you backed up today's work? http://www.lingnu.com/backup.html


================================================================= To unsubscribe, send mail to [EMAIL PROTECTED] with the word "unsubscribe" in the message body, e.g., run the command echo unsubscribe | mail [EMAIL PROTECTED]



Reply via email to