Search code examples
c++ccharvariadic-functionssizeof

sizeof(va_list) = 24 not 8


By definition, in stdarg.h typedef char* va_list.so the size of va_list should be 8 not 24 in ubuntu 20.04 64bits gcc 9.4.0, i don't know why i get the size of va_list is 24?

I runed the following codes:

#include <stdio.h>
#include <stdarg.h>
#include <stddef.h>
void print_num( int count, ...){
        va_list args;
        printf("sizeof(args):%d\n",sizeof(va_list));
        va_start(args,count);
        for( int i = 0; i < count; i++ ){
//            printf("*args = %d\n",va_arg(args,int));
              printf("*args = %d\n",*(int*)args);
              args += 4;
        }
        va_end(args);
}
int main(){
        print_num(5,1,2,3,4,5);
        return 0;
}

i expected printf 1 2 3 4 5 but i get an error:change_function.c:13:8: error: assignment to expression with array type 13 | args += 4; so i used the following method to print,but i don't know why the above code can get an error? i guess the source of the question is the type of the va_list. I would appreciate it if you could help me.

#include <stdio.h>
#include <stdarg.h>
#include <stddef.h>
void print_num( int count, ...){
        va_list args;
        printf("sizeof(args):%d\n",sizeof(va_list));
        va_start(args,count);
        for( int i = 0; i < count; i++ ){
                printf("*args = %d\n",va_arg(args,int));
//              printf("*args = %d\n",*(int*)args);


//      args += 4;
        }
        va_end(args);
}
int main(){
        print_num(5,1,2,3,4,5);
        return 0;
}

Thank you!!!


Solution

  • why i get the size of va_list is 24?

    You are most probably on x86_64 architecture using standard abi. From https://refspecs.linuxbase.org/elf/x86_64-abi-0.99.pdf page 53 valist is given as:

    typedef struct {
    unsigned int gp_offset;
    unsigned int fp_offset;
    void *overflow_arg_area;
    void *reg_save_area;
    } va_list[1]
    

    From page 12 the type unsigned int has 4 bytes, and a pointer on 64bit architecture has 64 bits so 8 bytes. So size of va_list on your architecture with this compiler and compiler options using that application binary interface is 4+4+8+8 = 24.

    Additionally, that document around pages 51-53 explains how variadic arguments are passed. For float values special floating point registers are used, which makes the "args += 4" method not possible to work on this abi.