c - Why does printf require a mandatory parameter? -
the definition of printf function in c language is:
int printf(const char * _format, ...);
the same scanf
, lot of similar functions managed variable number of arguments.
why there _format
mandatory parameter?
the format string mandatory because way c's variable argument macros work depends on @ least 1 argument being present, , using find others.
specifically, read other variable arguments, use va_start
(then va_arg
repeatedly, once each variable argument want read). when call va_start
, need pass format string (or, more generally, last non-varying parameter function).
for example, acts printf
, prints both stdout
, file of choice:
void tee(file *f, char const *fmt, ...) { va_list ap; va_start(ap, fmt); vprintf(fmt, ap); va_end(ap); va_start(ap, fmt); vfprintf(f, fmt, ap); va_end(ap); }
this uses vprintf
, vfprintf
, doesn't (directly) use va_arg
itself, va_start
, va_end
, that's enough show how fmt
involved in using va_start
.
at 1 time, wasn't needed. when c shiny , new, have function equivalent to: int f(...);
.
during first c standardization effort, however, eliminated in favor of macros noted above (va_start
, va_arg
, va_end
) require @ least 1 named parameter. older macros placed number of requirements on calling convention:
- parameters passed same way, regardless of type or number.
- it's easy find first argument passed.
with conventional c calling convention (all arguments passed on stack, arguments pushed right left) true. looked @ top of stack, moved backward past return address, , there first argument.
with other calling conventions, things weren't simple though. example, pushing arguments left right means first argument (the format string, in case of printf
) buried arbitrary distance down stack, arbitrary number of other arguments after it.
the way came deal pass previous (named) argument va_start
(and va_start macro use address of argument). if push right left, give address whatever distance needed down stack, va_arg
can walk up stack retrieve other variable arguments.
this apparently seen acceptable compromise, since functions take variable arguments take @ least 1 named parameter anyway.
Comments
Post a Comment