473,503 Members | 3,308 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

How can printf process variable parameters?

Hi friends!!

As we know that the input parameters in a function is fixed when the
function is defined but how does printf processes variable number of
input arguments ?

For example:

1. printf("Hey! how are you"); /*No. of arguments = 1*/
2. printf("Sum of %d and %d is %d",a,b,c"); /* No. of arguments = 4*/

I know it uses three macros va_start, va_arg, va_list ; but i don't
know how the stuff actually works...
Please explain.

Thanks in advance!!

Gaurav

Oct 1 '07 #1
11 11035
Googy wrote:
Hi friends!!

As we know that the input parameters in a function is fixed when the
function is defined but how does printf processes variable number of
input arguments ?
[...]
I know it uses three macros va_start, va_arg, va_list ; but i don't
know how the stuff actually works...
Please explain.
Start here: <http://c-faq.com/varargs/index.html>

Most good C books will give you a gentle introduction to variable-length
argument lists. K&R references them a few times.
--
clvrmnky <mailto:sp******@clevermonkey.org>

Direct replies will be blacklisted. Replace "spamtrap" with my name to
contact me directly.
Oct 1 '07 #2
On 1 Oct, 18:28, Googy <cool.gaurav.ignit...@gmail.comwrote:
Hi friends!!

As we know that the input parameters in a function is fixed when the
function is defined but how does printf processes variable number of
input arguments ?

For example:

1. printf("Hey! how are you"); /*No. of arguments = 1*/
2. printf("Sum of %d and %d is %d",a,b,c"); /* No. of arguments = 4*/

I know it uses three macros va_start, va_arg, va_list ; but i don't
know how the stuff actually works...
Please explain.
The printf() function is implementation-defined,
and therefore need not use these va_*** tokens.
It is "undefined behaviour" to pass arguments
which do not match, in their successive types and
total number, the field codes in the format string,
therefore the printf() function can be implemented
to assume that these codes can be used to derive
the number and type of the arguments, rather than
va_start etcetera.
--

Oct 1 '07 #3
On Oct 1, 1:28 pm, Googy <cool.gaurav.ignit...@gmail.comwrote:
Hi friends!!

As we know that the input parameters in a function is fixed when the
function is defined but how does printf processes variable number of
input arguments ?

For example:

1. printf("Hey! how are you"); /*No. of arguments = 1*/
2. printf("Sum of %d and %d is %d",a,b,c"); /* No. of arguments = 4*/

I know it uses three macros va_start, va_arg, va_list ; but i don't
know how the stuff actually works...
Please explain.
It works by Magic.

Actually, it works by whatever mechanism the compiler writer chose to
use to implement va_start, et al. The mechanism is highly dependant on
the physical arrangement and location of arguments passed to a
function, and their format and promotions. That's why the macros are
made available; the underlying mechanisms are inherently non-portable,
and often obscure or convoluted.

One mechanism works only with a stack, and only if the arguments are
"pushed" onto the stack from right to left. With this mechanism, the
further "right" you go in the argument list, the higher the address on
the stack. To find any argument, you first need a starting point on
the stack, and then you need to know how much "up" the stack you have
to go, and how much /of/ the stack you have to inhale to make your
object up. In a case like that, the called function can take the
address of the left-most argument as the "base" or low point of the
stack. Knowing how big the object at this base point is, the function
can then compute the address of next object on the stack. Knowing the
size of /that/ object (by foreknowledge, or by parsing the contents of
the first object), the function can then compute the address of the /
next/ object. And so on. Now, you see why the standard makes this
opaque to the programmer, and gives him the va_* macros instead? It
needs a detailed understanding of the underlying parameter passing
implementation to work, and that's something that most application
programmers do not need.


Oct 1 '07 #4
Googy wrote:
Hi friends!!

As we know that the input parameters in a function is fixed when the
function is defined but how does printf processes variable number of
input arguments ?

For example:

1. printf("Hey! how are you"); /*No. of arguments = 1*/
2. printf("Sum of %d and %d is %d",a,b,c"); /* No. of arguments = 4*/

I know it uses three macros va_start, va_arg, va_list ; but i don't
know how the stuff actually works...
Please explain.

Thanks in advance!!

Gaurav
Easy one first.

If you take one vanilla implementation, like 32 bit windows
or 32 bit linux you have:
o A pointer to the start of the stack area where parameters are pushed
The macro va_start sets the va_list variable to point of the start
of the argument stack area.
o Then, each time you take out something from the va_list you increase
that pointer by sizeof(type) with appropiate rounding to a word size.

More difficult one:
Under the windows 64 operating system the first 4 arguments are
passed with the registers, no pushing into the stack. The above schema
would not work at all. Then, the va_list must point to a structure
where you have several pointers. One to the stack area where the
registers are saved, to pull possible values from them, then, a
pointer to the stack area where the arguments 5th to N are stored.
Interesting bugs can happen when you forget the 32 bytes of stack
offset that windows reserves, and the fact that floating point
registers are pulled from the SSE registers and integer/pointer
arguments are pulled from the integer registers.
Phew... took me a while.

HELL:
Absolute hell is of course, linux 64 bits. In that system, up
to 8 integer arguments can be passed in the integer registers,
up to 8 arguments can be passed in the floating point registers,
and the rest is passed in the stack... So, instead of just
looking at a single register save area you have to look to 2 of them
and maintain pointers to each one. Each pointer is incremented
independently, to the contrary of windows.

This is of course much more efficient schema than windows, but it is
pure hell for the compiler writer. Took me like a month of bug
after bug after bug.

For instance, structures are normally always passed in the stack, unless
they are smaller than a word...

--
jacob navia
jacob at jacob point remcomp point fr
logiciels/informatique
http://www.cs.virginia.edu/~lcc-win32
Oct 1 '07 #5
bert wrote:
On 1 Oct, 18:28, Googy <cool.gaurav.ignit...@gmail.comwrote:
>Hi friends!!

As we know that the input parameters in a function is fixed when the
function is defined but how does printf processes variable number of
input arguments ?

For example:

1. printf("Hey! how are you"); /*No. of arguments = 1*/
2. printf("Sum of %d and %d is %d",a,b,c"); /* No. of arguments = 4*/

I know it uses three macros va_start, va_arg, va_list ; but i don't
know how the stuff actually works...
Please explain.

The printf() function is implementation-defined,
and therefore need not use these va_*** tokens.
It is "undefined behaviour" to pass arguments
which do not match, in their successive types and
total number, the field codes in the format string,
therefore the printf() function can be implemented
to assume that these codes can be used to derive
the number and type of the arguments, rather than
va_start etcetera.
--
That would be quite a crazy strategy... Why wouldn't printf
use the va_start macros???

Do you have any implementation example at hand?

Or a description how could that work?
--
jacob navia
jacob at jacob point remcomp point fr
logiciels/informatique
http://www.cs.virginia.edu/~lcc-win32
Oct 1 '07 #6
On Mon, 01 Oct 2007 20:36:41 +0200, jacob navia wrote:
That would be quite a crazy strategy... Why wouldn't printf use the
va_start macros???

Do you have any implementation example at hand?

Or a description how could that work?
What if the implementation of the C library is written in assembly?
Oct 1 '07 #7
In article <fd**********@news3.zwoll1.ov.home.nl>,
$)CHarald van D )& k <tr*****@gmail.comwrote:
>That would be quite a crazy strategy... Why wouldn't printf use the
va_start macros???

Do you have any implementation example at hand?

Or a description how could that work?
>What if the implementation of the C library is written in assembly?
Even if it were written in assembler, it would be strange for it to
be detectably different from a version written using va_*.

It's been suggested here recently that it might even use an
incompatible argument passing protocol, so that the guarantees for
normal stdarg functions would not apply (in particular, it's been
suggested that you can't reliably pass a char * for a %p item). That
would certainly be crazy. printf() should work *as if by* the usual
protocol.

-- Richard
--
"Consideration shall be given to the need for as many as 32 characters
in some alphabets" - X3.4, 1963.
Oct 1 '07 #8
On Mon, 01 Oct 2007 20:50:34 +0000, Richard Tobin wrote:
In article <fd**********@news3.zwoll1.ov.home.nl>, $)CHarald van D )& k
<tr*****@gmail.comwrote:
Could you please leave in the attribution notices? The below text was
written by jacob navia.
>>That would be quite a crazy strategy... Why wouldn't printf use the
va_start macros???

Do you have any implementation example at hand?

Or a description how could that work?
>>What if the implementation of the C library is written in assembly?

Even if it were written in assembler, it would be strange for it to be
detectably different from a version written using va_*.
Agreed. I was merely giving a reason why it might not use <stdarg.h>. I
have given a possible reason why it would not behave as if implemented
using <stdarg.helsewhere, but I know it takes more effort to write a
conforming implementation where printf("%u\n", 10) would fail, than it
would to write one where it will work.
It's been suggested here recently that it might even use an incompatible
argument passing protocol, so that the guarantees for normal stdarg
functions would not apply (in particular, it's been suggested that you
can't reliably pass a char * for a %p item). That would certainly be
crazy. printf() should work *as if by* the usual protocol.
It's not allowed to use an incompatible argument passing protocol (except
under the "as if" rule). You can safely assign printf to a properly
declared function pointer, and then call it from a unit where knowledge
that printf is present in the project at all is not available. It's
allowed to use an incompatible argument *retrieval* protocol, but except
for an extremely strict debugging implementation, it would make
absolutely no sense to do so.
Oct 1 '07 #9
In article <fd**********@news2.zwoll1.ov.home.nl>,
Harald van D )& k <tr*****@gmail.comwrote:
>It's not allowed to use an incompatible argument passing protocol (except
under the "as if" rule). You can safely assign printf to a properly
declared function pointer, and then call it from a unit where knowledge
that printf is present in the project at all is not available. It's
allowed to use an incompatible argument *retrieval* protocol, but except
for an extremely strict debugging implementation, it would make
absolutely no sense to do so.
It's quite hard to imagine a compatible argument passing protocol
without a compatible argument retrieval protocol. If the caller does
the same thing with char * and void *, how is the callee (printf())
going to get it wrong?

Quite hard, but not impossible... I suppose the caller could, say,
store void * arguments in two locations, but char * in only one, and
have printf() extract the argument from the extra location. I vaguely
remember something about 68000s returning pointers in both address and
data registers (Chris Torek?) but in this case it would be entirely
gratuitous.

Do you think it was really the intention of the standard authors to
allow such an implementation?

-- Richard
--
"Consideration shall be given to the need for as many as 32 characters
in some alphabets" - X3.4, 1963.
Oct 1 '07 #10
On Mon, 01 Oct 2007 22:33:52 +0000, Richard Tobin wrote:
In article <fd**********@news2.zwoll1.ov.home.nl>, Harald van D )& k
<tr*****@gmail.comwrote:
>>It's not allowed to use an incompatible argument passing protocol
(except under the "as if" rule). You can safely assign printf to a
properly declared function pointer, and then call it from a unit where
knowledge that printf is present in the project at all is not available.
It's allowed to use an incompatible argument *retrieval* protocol, but
except for an extremely strict debugging implementation, it would make
absolutely no sense to do so.

It's quite hard to imagine a compatible argument passing protocol
without a compatible argument retrieval protocol. If the caller does
the same thing with char * and void *, how is the callee (printf())
going to get it wrong?
The compiler might have built-in knowledge for *printf, and cause _any_
type mismatch to cause a nonfatal compile-time diagnostic and a fatal
runtime diagnostic. Meaning:

#include <stdio.h>
int main(void) {
printf("%d\n", "Hello");
printf("%d\n", 1u);
}

would generate diagnostics such as

example.c:3:type mismatch in argument to 'printf', will abort at runtime
example.c:4:type mismatch in argument to 'printf', will abort at runtime

Or, type info could be passed to the function along with type arguments,
and *printf would verify for exact type matches, while va_arg would
contain extra code to allow for sloppy matches.
Quite hard, but not impossible... I suppose the caller could, say, store
void * arguments in two locations, but char * in only one, and have
printf() extract the argument from the extra location.
That's another possibility.
I vaguely
remember something about 68000s returning pointers in both address and
data registers (Chris Torek?) but in this case it would be entirely
gratuitous.
This is true.
Do you think it was really the intention of the standard authors to
allow such an implementation?
No, I don't think so. I do believe the special permissions on va_arg are
intended for compatibility only, but I would be surprised if they were
not intended to be permitted in any variadic function call.
Oct 1 '07 #11
On Mon, 01 Oct 2007 10:28:14 -0700, Googy
<co******************@gmail.comwrote in comp.lang.c:
Hi friends!!

As we know that the input parameters in a function is fixed when the
function is defined
No, we don't know this. You may think you know this, but you are
wrong. If you were right, the *printf() and *scanf() functions would
not be a part of the standard C library. And the <stdarg.hheader
would be useless.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://c-faq.com/
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.club.cc.cmu.edu/~ajo/docs/FAQ-acllc.html
Oct 2 '07 #12

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
2535
by: comingupslowly | last post by:
Hi I have a PHP problem I can't solve. I'm using variable names as class constructors in a project, a la: $foo = "ClassName"; $bar = new $foo(); But what I can't work out is how to pass...
3
2664
by: zimba | last post by:
Hello, Do you know a better way to : - instanciate a class with an unknown number of parameters in the constructor - call an object's method, also with an unknown number of parameters ? ...
3
4804
by: Edward | last post by:
ASP.NET / VB.NET SQL Server 7.0 Our client has insisted that we change our established practice of building SQL in-line and move it all to SPROCs. Not a problem for 80% of the app. However,...
4
9848
by: shaggystyle | last post by:
I'm looking for a way to call system commands with variable parameters within a Unix environment. Sort of like system() but i need to be able to pass variable parameters....so I guess it would...
3
1754
by: martin.druon | last post by:
Hi, I created a template class to represent hypermatrix. I would like to add methods where the number of parameters are checked during the compilation time. For example : template <size_t...
5
5805
by: rbfish | last post by:
Hi, How can I call a virtual base function with variable parameters? like, class base { public: int printf(const char *fmt, ...) { // do anything here.
9
10905
by: anilcool | last post by:
Hi all, Another novice question. I want to insert multiple records into my DB2 database using stored procedure but I do not know how many I would like to insert at any given time. Each record...
3
2087
by: John Shell | last post by:
Hello, all. The following code results in a C2666 error (2 overloads have similar conversions). class FSVec2D { public: FSVec2D() { // code omitted }
2
1012
by: =?Utf-8?B?cm9kY2hhcg==?= | last post by:
hey all, if i have a function that i'm passing the name of a stored procedure to and i don't know if the stored procedure is going to have parameters or not what's the perferred way to handle this...
0
7192
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
7261
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
7315
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
1
6974
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
1
4991
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...
0
4665
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...
0
3158
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The...
1
721
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
0
369
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.