How are variable arguments implemented in gcc?

后端 未结 4 568
无人及你
无人及你 2020-11-27 04:51
int max(int n, ...)

I am using cdecl calling convention where the caller cleans up the variable after the callee returns.

I a

4条回答
  •  时光说笑
    2020-11-27 05:41

    Generically, how I grok target.def, when a function prototype is declared with ( ,...) the compiler sets up a parse tree marked with a varargs flag and references to the types of the named arguments. For strict C conformance each named argument should get whatever additional info is necessary appended to setup a va_list when that parameter is the named field of va_start and as a possible return to va_arg(), but most compilers just generate this info for the last named argument. When the function is defined its prologue generator notes the varargs flag was set and adds the code necessary to set up any hidden fields it adds to the frame that have known offsets the va_start macro can reference.

    When it finds a reference to that function it creates additional parse and code generation trees for each argument representing the ..., that may introduce additional hidden fields of runtime type info, such as array bounds, that is appended to the fields setup for va_start and va_arg for the named arguments. This combined tree determines what code gets generated to copy the parameter values onto the frame, the prologue sets up what's necessary for va_start to create a va_list starting at an arbitrary or last named parameter, and each invocation of va_arg() generates inline code that references any parameter specific hidden fields used to validate at compile time the expected return is assignment compatible with the expression usage being compiled, and perform any required argument promotions/coercions. The sum of named field value sizes and hidden field sizes determines what value is compiled after the call, or in the function epilogue for callee cleanup models, to adjust the frame upon return.

    Each of these steps has processor and calling convention dependencies, encapsulated in the config/proc/proc.c and proc.h files, that override the simplistic default definitions of va_start() and va_arg() that assume each argument has a fixed size allocated some distance above the first named argument on a stack. For some platforms or languages parameter frames implemented as separate malloc()s are more desirable than a fixed size stack. Also note these usages are not thread safe; it is unsafe to pass a va_list reference to another thread without unspecified means of ensuring the parameter frame is not made invalid due to function return or abort of the thread.

提交回复
热议问题