Or no explicit parameters at all ... void do_something (T1 t1, T2 t2) __attribute__ ((caller_info));
All this will do (with appropriate compilation switches and/or pre-defined macros) is pass one/more hidden arguments, which in turn can be accessed in the function body via a built-in function. #if CALLER_INFO_ENABLED __caller_info_t caller_info = __builtin_caller_info (); [...] #endif In this way, the programmer-visible function prototype is unaffected, though the caller and the function body have to be compiled with compatible settings.