M Zeinstra
M Zeinstra

Reputation: 1981

Way of casting in va_arg

I'm doing some research about variadic functions and arguments.

I noticed that va_arg is able to cast objects into other objects. For example, when the next argument is a char, but you are using va_arg like it should be an int, it casts the char to an int:

Function call:

AddNumbers(3, 5, 'a', 20);

Function declaration:

int AddNumbers(int count, ...) {
    int result;

    va_list va;
    va_start(va, count);
    for(int i = 0; i < count; ++i) {
        result += va_arg(va, int);
    }
    return result;
}

So my question is: what kind of casting does this function use (C-style, dynamic_cast, etc.)?

Upvotes: 2

Views: 1643

Answers (3)

Serge Ballesta
Serge Ballesta

Reputation: 149185

It is not exactly casting, because va_arg is a macro, not a function. So the type of va_arg(va, int) is by construction int.

But promotions do occur when calling the variadic function (except for the argument preceding the ellipsis.

So in AddNumbers(3, 5, 'a', 20);, the character 'a' is promoted to an int. You can then either use it as an int as your code does, or convert it back to a char (a conversion not a cast) which is defined because the int value can be represented as a char (by construction)

Upvotes: 1

Some programmer dude
Some programmer dude

Reputation: 409472

It has nothing to do with casting. In this case it works because of argument promotion.

When you use a varargs function, integer types smaller than int (like e.g. char) are promoted to int.

That's why it works when passing character literals to the function. If you try some other type, like e.g. a floating point value, then it will no longer work.

As for what the va_arg macro (it's mostly implemented as a macro) does, it is totally implementation dependent. It might not do any casting at all, but use some other form of type punning instead.

Upvotes: 4

Josh Kelley
Josh Kelley

Reputation: 58442

If I understand your question correctly:

C performs certain "casts" by default when calling a variadic function. GCC calls these default argument promotions. They are:

  • Signed or unsigned char and short int become signed or unsigned int.
  • float becomes double.

This isn't really a matter of va_arg doing a cast within AddNumbers; instead, when calling AddNumbers, the caller promotes the arguments to AddNumbers as part of pushing them onto the stack for AddNumbers to use.

Upvotes: 1

Related Questions