gcc: Constructing Calls
1
1 6.5 Constructing Function Calls
1 ===============================
1
1 Using the built-in functions described below, you can record the
1 arguments a function received, and call another function with the same
1 arguments, without knowing the number or types of the arguments.
1
1 You can also record the return value of that function call, and later
1 return that value, without knowing what data type the function tried to
1 return (as long as your caller expects that data type).
1
1 However, these built-in functions may interact badly with some
1 sophisticated features or other extensions of the language. It is,
1 therefore, not recommended to use them outside very simple functions
1 acting as mere forwarders for their arguments.
1
1 -- Built-in Function: void * __builtin_apply_args ()
1 This built-in function returns a pointer to data describing how to
1 perform a call with the same arguments as are passed to the current
1 function.
1
1 The function saves the arg pointer register, structure value
1 address, and all registers that might be used to pass arguments to
1 a function into a block of memory allocated on the stack. Then it
1 returns the address of that block.
1
1 -- Built-in Function: void * __builtin_apply (void (*FUNCTION)(), void
1 *ARGUMENTS, size_t SIZE)
1 This built-in function invokes FUNCTION with a copy of the
1 parameters described by ARGUMENTS and SIZE.
1
1 The value of ARGUMENTS should be the value returned by
1 '__builtin_apply_args'. The argument SIZE specifies the size of
1 the stack argument data, in bytes.
1
1 This function returns a pointer to data describing how to return
1 whatever value is returned by FUNCTION. The data is saved in a
1 block of memory allocated on the stack.
1
1 It is not always simple to compute the proper value for SIZE. The
1 value is used by '__builtin_apply' to compute the amount of data
1 that should be pushed on the stack and copied from the incoming
1 argument area.
1
1 -- Built-in Function: void __builtin_return (void *RESULT)
1 This built-in function returns the value described by RESULT from
1 the containing function. You should specify, for RESULT, a value
1 returned by '__builtin_apply'.
1
1 -- Built-in Function: __builtin_va_arg_pack ()
1 This built-in function represents all anonymous arguments of an
1 inline function. It can be used only in inline functions that are
1 always inlined, never compiled as a separate function, such as
1 those using '__attribute__ ((__always_inline__))' or '__attribute__
1 ((__gnu_inline__))' extern inline functions. It must be only
1 passed as last argument to some other function with variable
1 arguments. This is useful for writing small wrapper inlines for
1 variable argument functions, when using preprocessor macros is
1 undesirable. For example:
1 extern int myprintf (FILE *f, const char *format, ...);
1 extern inline __attribute__ ((__gnu_inline__)) int
1 myprintf (FILE *f, const char *format, ...)
1 {
1 int r = fprintf (f, "myprintf: ");
1 if (r < 0)
1 return r;
1 int s = fprintf (f, format, __builtin_va_arg_pack ());
1 if (s < 0)
1 return s;
1 return r + s;
1 }
1
1 -- Built-in Function: size_t __builtin_va_arg_pack_len ()
1 This built-in function returns the number of anonymous arguments of
1 an inline function. It can be used only in inline functions that
1 are always inlined, never compiled as a separate function, such as
1 those using '__attribute__ ((__always_inline__))' or '__attribute__
1 ((__gnu_inline__))' extern inline functions. For example following
1 does link- or run-time checking of open arguments for optimized
1 code:
1 #ifdef __OPTIMIZE__
1 extern inline __attribute__((__gnu_inline__)) int
1 myopen (const char *path, int oflag, ...)
1 {
1 if (__builtin_va_arg_pack_len () > 1)
1 warn_open_too_many_arguments ();
1
1 if (__builtin_constant_p (oflag))
1 {
1 if ((oflag & O_CREAT) != 0 && __builtin_va_arg_pack_len () < 1)
1 {
1 warn_open_missing_mode ();
1 return __open_2 (path, oflag);
1 }
1 return open (path, oflag, __builtin_va_arg_pack ());
1 }
1
1 if (__builtin_va_arg_pack_len () < 1)
1 return __open_2 (path, oflag);
1
1 return open (path, oflag, __builtin_va_arg_pack ());
1 }
1 #endif
1