1

I'm searching for answers but i can't find any relevant information on this. Let's take the example:

class MyClass
{
    //member functions and variables
};

void foo(int pivot,...)
{
    va_list arguments;  
    va_start(arguments,pivot);

    //va_arg(arguments,???)

    va_end(arguments);
}

void bar()
{
    MyClass a;
    MyClass * b = &a;
    const MyClass & c = a;
    foo(0,a,b,c);
}

How are the arguments a,b and c passed? By value , or by reference and how to ask for them using va_arg? What about the constructors/destructor for MyClass? Where in the c++ standard is this kind of behavior specified?

11

2 Answers 2

5

You should never use user-defined types in var-arg function. Use C++11 variadic templates.

If your class is not pod-type - it's unspecified by standard, thanks to Vaughn Cato for remark

n3337 5.2.2/7

Passing a potentially-evaluated argument of class type (Clause 9) having a nontrivial copy constructor, a non-trivial move constructor, or a non-trivial destructor, with no corresponding parameter, is conditionally-supported with implementation-defined semantics.

Else, you can and it will be correct, but you shouln't.

Sign up to request clarification or add additional context in comments.

2 Comments

Then it should be safe just to use MyClass* only if really needed. I tested this msvc and it seems to be legit.
And of course, he doesn't show enough for us to conclude that MyClass is not a POD. Although traditionally, POD classes are defined with the struct keyword, something like class MyClass { public : int a; int b; }; is perfectly legal, and is a POD.
3

By value. But beware, if MyClass is not a POD, the program has undefined behavior (C++03, §5.2.2/7), or if MyClass has a non-trivial copy constructor, move constructor or destructor, the operation is conditionally supported, with implementation defined semantics (C++11, §5.2.2/7).

In your example, passing a and passing c are exactly identical operations (except that c cannot be bound to a non-const reference, but that's not an issue here, since varargs are all pass by value). Thus, when calling foo, you pass 0, a copy of a, a copy of the pointer b, and a copy of a. In order to access them in foo, you need to declare the types in va_arg as int, MyClass, MyClass* and MyClass.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.