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 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.
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.
--
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.
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
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
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?
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.
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.
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.
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. This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics |
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...
|
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
?
...
|
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,...
|
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...
|
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...
| |
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.
|
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...
|
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
}
|
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...
|
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,...
|
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,...
| |
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...
|
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...
|
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...
|
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...
|
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...
|
by: muto222 |
last post by:
How can i add a mobile payment intergratation into php mysql website.
| |
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...
| |