By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
432,086 Members | 1,919 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 432,086 IT Pros & Developers. It's quick & easy.

Strange behaviour of printf. See the code below and please tell why it behaves in this way.

P: n/a
#include<stdio.h>
typedef struct test{
int i;
int j;
}test;

main(){
test var;
var.i=10;
var.j=20;

printf("i==%d i==%d \n",var,var.i);
return 1;
}

Compiler in VC++ and see that you get the output is i==10 i==20

Can any one explain Why this thing happens?even though i give the
address of var.i why the value of j is geting printed?

Nov 14 '05 #1
Share this Question
Share on Google+
31 Replies


P: n/a
DeltaOne wrote:

#include<stdio.h>
typedef struct test{
int i;
int j;
}test;

main(){
test var;
var.i=10;
var.j=20;

printf("i==%d i==%d \n",var,var.i);
return 1;
}

Compiler in VC++ and see that you get the output is i==10 i==20

Can any one explain Why this thing happens?even though i give the
address of var.i
You're not.
(int *)&var is the address of var.i.
&var.i is the address of var.i.
why the value of j is geting printed?


Even if you were giving it the address of var.i,
%d is for int type arguments, not pointers,
so the meaning of your code is undefined
and anything can happen.

--
pete
Nov 14 '05 #2

P: n/a
Hello

DeltaOne wrote:
#include<stdio.h>
typedef struct test{
int i;
int j;
}test;

main(){
test var;
var.i=10;
var.j=20;

printf("i==%d i==%d \n",var,var.i);
return 1;
}

Compiler in VC++ and see that you get the output is i==10 i==20
VC++ ought to reject this code, as it is not valid C++. However, you're
asking in a C group about C code, so I assume you really want to compile
this as a C program. Then the compiler should warn for several reasons.

Firstly, as far as I know, implicit int declaration is discouraged even in
C. Secondly, the compiler will notice that the arguments of printf don't
match the format string. This is also the reason for the observed
behaviour.
You're supplying a struct test, then an int. printf expects two ints.
Now accidentally your struct test is nothing but two ints (i and j).
These are printed.

GCC says:
7: warning: return type defaults to `int'
In function `main':
12: warning: int format, test arg (arg 2)
Can any one explain Why this thing happens?even though i give the
address of var.i why the value of j is geting printed?


You're not giving any addresses.
This would require a pointer, like &var.i.

Markus

Nov 14 '05 #3

P: n/a
DeltaOne wrote:
#include<stdio.h>
typedef struct test{
int i;
int j;
}test;

main(){
test var;
var.i=10;
var.j=20;

printf("i==%d i==%d \n",var,var.i);
return 1;
}

Compiler in VC++ and see that you get the output is i==10 i==20

Can any one explain Why this thing happens?even though i give the
address of var.i why the value of j is geting printed?


It is happening because you invoked undefined behaviour on your specific
system before 18th May 2005. I would suggest not trying it tomorrow as
it might cause a dark lord of the Sith to come round and kill you.

Specifically, you passed var which is a struct to printf when in the
format specifier you promised to pass an int.
--
Flash Gordon
Living in interesting times.
Although my email address says spam, it is real and I read it.
Nov 14 '05 #4

P: n/a
On 17 May 2005 05:03:00 -0700, DeltaOne
<sh**********@wipro.com> wrote:
#include<stdio.h>
typedef struct test{
int i;
int j;
}test;

main(){
For a start, main should be declared as int main(void) (or the two
argument version). "Implicit int" is not supported in later (C99)
compilers. This isn't the problem, but is good practice to do always.
test var;
var.i=10;
var.j=20;

printf("i==%d i==%d \n",var,var.i);
Your compiler should give a diagnostic here. GCC, for instance, will
give:

warning: int format, test arg (arg 2)

if you turn warnings on telling you that there's a mismatch.
return 1;
Returning 1 from main() is not specified, the only guaranteed values
supported are zero, EXIT_SUCCESS and EXIT_FAILURE (the latter two
defined in stdlib.h).
}

Compiler in VC++ and see that you get the output is i==10 i==20

Can any one explain Why this thing happens?even though i give the
address of var.i why the value of j is geting printed?


You don't give the address, you pass the structure 'var' by value. As
it happens, this structure is two ints so it looks to printf like
passing var.i and var.j as parameters (with an extra var.i on the end
which is ignored). Other compilers might do other things, including
crash at runtime, if you pass a structure to printf()...

Chris C
Nov 14 '05 #5

P: n/a
Chris Croughton wrote:

On 17 May 2005 05:03:00 -0700, DeltaOne
<sh**********@wipro.com> wrote:

printf("i==%d i==%d \n",var,var.i);


Your compiler should give a diagnostic here.


It's a good thing to warn about
but it's not required by the rules of C.
Nov 14 '05 #6

P: n/a
"DeltaOne" <sh**********@wipro.com> wrote:
# #include<stdio.h>
# typedef struct test{
# int i;
# int j;
# }test;
#
# main(){
# test var;
# var.i=10;
# var.j=20;
#
# printf("i==%d i==%d \n",var,var.i);
# return 1;
# }
#
# Compiler in VC++ and see that you get the output is i==10 i==20
#
# Can any one explain Why this thing happens?even though i give the
# address of var.i why the value of j is geting printed?

When you pass a struct by value, all the fields of the struct are placed in
the argument list in order, along with any padding. Your call is equivalent to

printf("i==%d i==%d \n",var.i,var.j,var.i);

--
SM Ryan http://www.rawbw.com/~wyrmwif/
There are subtler ways of badgering a witness.
Nov 14 '05 #7

P: n/a
SM Ryan <wy*****@tango-sierra-oscar-foxtrot-tango.fake.org> writes:
"DeltaOne" <sh**********@wipro.com> wrote:
#include<stdio.h>
typedef struct test{
int i;
int j;
}test;

main(){
test var;
var.i=10;
var.j=20;

printf("i==%d i==%d \n",var,var.i);
return 1;
}

Compiler in VC++ and see that you get the output is i==10 i==20

Can any one explain Why this thing happens?even though i give the
address of var.i why the value of j is geting printed?


When you pass a struct by value, all the fields of the struct are
placed in the argument list in order, along with any padding. Your
call is equivalent to

printf("i==%d i==%d \n",var.i,var.j,var.i);


[ Obnoxious '#' quoting character altered, obnoxious long lines
reformatted. ]

It probably happens to behave equivalently on the OP's particular
implementation. The call invokes undefined behavior, and could behave
differently for any of a number of reasons. Just a few possibilities
off the top of my head:

The order in which arguments are passed could differ from the
order in which struct members are allocated.

Integer arguments could occupy more than sizeof(int) bytes on the
stack (for example, if int is 32 bits but the CPU works more
naturally with 64-bit quantities).

Arguments could be passed in registers (this is admittedly less
likely for functions with a variable number of arguments).

Structures, like all parameters, are passed by value, but the
value actually passed to the function (on the machine level) could
be the address of a copy of the structure.

It's true that the behavior the OP saw is one of the more likely forms
that this undefined behavior can take.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 14 '05 #8

P: n/a
On Wed, 18 May 2005 10:04:40 GMT, Keith Thompson <ks***@mib.org> wrote:

Boy, this is my day for disagreeing with the gurus.
The order in which arguments are passed could differ from the
order in which struct members are allocated.
Would not this violate the as-if rule?

Structures, like all parameters, are passed by value, but the
value actually passed to the function (on the machine level) could
be the address of a copy of the structure.


This definitely would violate the as-if rule. Changes to the fields of the
struct would be made to the original data.
--
#include <standard.disclaimer>
_
Kevin D Quitt USA 91387-4454 96.37% of all statistics are made up
Nov 14 '05 #9

P: n/a
In article <am********************************@4ax.com>,
Kevin D. Quitt <KQ****@IEEInc.com> wrote:


On Wed, 18 May 2005 10:04:40 GMT, Keith Thompson <ks***@mib.org> wrote:

Boy, this is my day for disagreeing with the gurus.
The order in which arguments are passed could differ from the
order in which struct members are allocated.
Would not this violate the as-if rule?

Structures, like all parameters, are passed by value, but the
value actually passed to the function (on the machine level) could
be the address of a copy of the structure.

^^^^
This definitely would violate the as-if rule. Changes to the fields of the
struct would be made to the original data.


Nov 14 '05 #10

P: n/a
DeltaOne wrote on 17/05/05 :
#include<stdio.h>
typedef struct test{
int i;
int j;
}test;

main(){
test var;
var.i=10;
var.j=20;

printf("i==%d i==%d \n",var,var.i);
return 1;
}


Considering this

main.c: In function `main_':
main.c:23: warning: int format, test arg (arg 2)

The behaviour is undefined.

All bets are off.

--
Emmanuel
The C-FAQ: http://www.eskimo.com/~scs/C-faq/faq.html
The C-library: http://www.dinkumware.com/refxc.html

..sig under repair

Nov 14 '05 #11

P: n/a
Markus Moll wrote on 17/05/05 :
Compiler in VC++ and see that you get the output is i==10 i==20


VC++ ought to reject this code, as it is not valid C++.


VC++ supports C and C++. Depends on the source file extension.

--
Emmanuel
The C-FAQ: http://www.eskimo.com/~scs/C-faq/faq.html
The C-library: http://www.dinkumware.com/refxc.html

..sig under repair

Nov 14 '05 #12

P: n/a
SM Ryan wrote on 18/05/05 :
When you pass a struct by value, all the fields of the struct are placed in
the argument list in order, along with any padding. Your call is equivalent
to

printf("i==%d i==%d \n",var.i,var.j,var.i);


No. The behaviour is undefined. Period.

--
Emmanuel
The C-FAQ: http://www.eskimo.com/~scs/C-faq/faq.html
The C-library: http://www.dinkumware.com/refxc.html

"Mal nommer les choses c'est ajouter du malheur au
monde." -- Albert Camus.

Nov 14 '05 #13

P: n/a
Kevin D. Quitt <KQ****@IEEInc.com> writes:
On Wed, 18 May 2005 10:04:40 GMT, Keith Thompson <ks***@mib.org> wrote:

Boy, this is my day for disagreeing with the gurus.
The order in which arguments are passed could differ from the
order in which struct members are allocated.


Would not this violate the as-if rule?


No, I don't see how. The code in question passed a
struct {int i; int j; }
value to a function expecting two ints. The standard requires j to
have a higher address and offset within the structure than j; it says
nothing about the relative addresses of two int arguments.
Structures, like all parameters, are passed by value, but the
value actually passed to the function (on the machine level) could
be the address of a copy of the structure.


This definitely would violate the as-if rule. Changes to the fields of the
struct would be made to the original data.


I said the address of *a copy of* the structure. Changing the copy
would have no effect on the the original.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 14 '05 #14

P: n/a
Keith Thompson <ks***@mib.org> writes:
Kevin D. Quitt <KQ****@IEEInc.com> writes:

[...]
Would not this violate the as-if rule?


No, I don't see how. The code in question passed a
struct {int i; int j; }
value to a function expecting two ints. The standard requires j to
have a higher address and offset within the structure than j; it says
nothing about the relative addresses of two int arguments.


That was a typo; I meant that j has a higher offset than *i*.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 14 '05 #15

P: n/a
"Emmanuel Delahaye" <em***@YOURBRAnoos.fr> wrote:

# No. The behaviour is undefined. Period.

How wonderfully unhelpful.
Actually anti-helpful.

A question was asked on an observed behaviour, so the behaviour was defined
on that implementation.

--
SM Ryan http://www.rawbw.com/~wyrmwif/
You hate people.
But I love gatherings. Isn't it ironic.
Nov 14 '05 #16

P: n/a
SM Ryan wrote:
"Emmanuel Delahaye" <em***@YOURBRAnoos.fr> wrote:

# No. The behaviour is undefined. Period.

How wonderfully unhelpful.
Actually anti-helpful.

A question was asked on an observed behaviour, so the behaviour was
defined on that implementation.


No, the only thing you can say was that behaviour was _observed_.

Defined behaviour is predictable and generally reproducable. Undefined
behaviour does not guarantee that. The OP may well change their mp3
player settings or such and observe completely different behaviour from
a piece of C code with undefined behaviour. [No, I'm not joking. Such
capriciousness is not unheard of.]

Modern computing has long moved past the era of defining language
behaviour in terms of what is observed on a given implementation.

It is dangerous to encourage the thought that because a given behaviour
is observed on a given machine, that other machines (or even the same
machine with a slightly different setup) will produce the same results.

Programs should be _demonstrably_, i.e. provably, correct as much as
possible. Where code goes beyond the standards, such code should be
justified in terms of other authoritative documentation, _not_
empirical
observation.

--
Peter

Nov 14 '05 #17

P: n/a
SM Ryan <wy*****@tango-sierra-oscar-foxtrot-tango.fake.org> writes:
"Emmanuel Delahaye" <em***@YOURBRAnoos.fr> wrote:
No. The behaviour is undefined. Period.


How wonderfully unhelpful.
Actually anti-helpful.

A question was asked on an observed behaviour, so the behaviour was defined
on that implementation.


[ Obnoxious quoting character '#' changed to '>'. ]

It's only unhelpful if you're not willing to learn from it.

The behavior is undefined. That doesn't mean it's not useful to
understand why it behaves the way it does on a particular
implementation; that can be a valuable way to track down the bug. But
understanding that passing a struct { int i; int j; } to a function
that expects two int arguments happens to behave a particular way on a
particular implementation is the beginning of understanding the
problem, not the end of it.

In your earlier followup, you wrote:

When you pass a struct by value, all the fields of the struct are
placed in the argument list in order, along with any padding. Your
call is equivalent to

printf("i==%d i==%d \n",var.i,var.j,var.i);

In fact, it is equivalent only by coincidence, and only under some
implementations. The behavior is "defined" on that implementation
only if the documentation explicitly guarantees the behavior. The OP
could easily have inferred that his code was valid; that's worse than
unhelpful.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 14 '05 #18

P: n/a
"Peter Nilsson" <ai***@acay.com.au> wrote:
# SM Ryan wrote:
# > "Emmanuel Delahaye" <em***@YOURBRAnoos.fr> wrote:
# >
# > # No. The behaviour is undefined. Period.
# >
# > How wonderfully unhelpful.
# > Actually anti-helpful.
# >
# > A question was asked on an observed behaviour, so the behaviour was
# > defined on that implementation.
#
# No, the only thing you can say was that behaviour was _observed_.

No it was defined in that implementation. Once you have some real world experience,
you will discover argument list and argument passing are always meticulously
well defined in each implementation. This allows linkages between the code of
one compiler and another--an important real world consideration. Often the
argument passing is not even left up the compiler: the CPU designer defines
external linkage protocols and all compilers for that CPU. Internal linkages,
in C that would mean calling a static function, can follow alternate protocols
but often don't except for optimising compilers.

# Defined behaviour is predictable and generally reproducable. Undefined

External linkages for a CPU are very predictable. They are usually defined
above the needs of C because they are intended to serve all languages on the
CPU.

You could gently point out to the original poster that external linkage
protocols might differ on different machines, but this would not change
the well-definedness of the observed behaviour. And anybody with any kind
of compiler writing experience would quickly understand from the observations
what had happenned. That your own knowledge is too limited is perhaps a good
reason to butt out.

# behaviour does not guarantee that. The OP may well change their mp3
# player settings or such and observe completely different behaviour from
# a piece of C code with undefined behaviour. [No, I'm not joking. Such
# capriciousness is not unheard of.]

Any CPU and/or compiler like that would be deemed broken and a commercial
failure.

# It is dangerous to encourage the thought that because a given behaviour
# is observed on a given machine, that other machines (or even the same
# machine with a slightly different setup) will produce the same results.

You can always point that out in a gentle and polite fashion.

Screaming off with their topic! off with their topic! like some kind of
manical red queen gives no help whatsoever and only contributes to the
ant-social behaviour and cliqueness of the modern comp.lang.c.

--
SM Ryan http://www.rawbw.com/~wyrmwif/
Raining down sulphur is like an endurance trial, man. Genocide is the
most exhausting activity one can engage in. Next to soccer.
Nov 14 '05 #19

P: n/a
On Wed, 18 May 2005 20:54:31 GMT, Keith Thompson <ks***@mib.org> wrote:

Kevin D. Quitt <KQ****@IEEInc.com> writes:
On Wed, 18 May 2005 10:04:40 GMT, Keith Thompson <ks***@mib.org> wrote:

Boy, this is my day for disagreeing with the gurus.

Zero for two.

I said the address of *a copy of* the structure. Changing the copy
would have no effect on the the original.


Yep. I need new glasses. Or eyes. Or brain.
--
#include <standard.disclaimer>
_
Kevin D Quitt USA 91387-4454 96.37% of all statistics are made up
Nov 14 '05 #20

P: n/a
On Thu, 19 May 2005 10:50:07 -0000, SM Ryan
<wy*****@tango-sierra-oscar-foxtrot-tango.fake.org> wrote:

"Peter Nilsson" <ai***@acay.com.au> wrote:
No, the only thing you can say was that behaviour was _observed_.


No it was defined in that implementation.


"Defined in that implementation" is not a meaningful phrase. "Defined"
means it comes from the Standard. And even by your definition you can't say
it was defined in the implementation, the observed behaviour might be
entirely an accident. The code's behaviour is undefined, by definition.

--
#include <standard.disclaimer>
_
Kevin D Quitt USA 91387-4454 96.37% of all statistics are made up
Nov 14 '05 #21

P: n/a
SM Ryan <wy*****@tango-sierra-oscar-foxtrot-tango.fake.org> writes:
"Peter Nilsson" <ai***@acay.com.au> wrote:
SM Ryan wrote:
"Emmanuel Delahaye" <em***@YOURBRAnoos.fr> wrote:

> No. The behaviour is undefined. Period.

How wonderfully unhelpful.
Actually anti-helpful.

A question was asked on an observed behaviour, so the behaviour was
defined on that implementation.


No, the only thing you can say was that behaviour was _observed_.


No it was defined in that implementation. Once you have some real
world experience, you will discover argument list and argument
passing are always meticulously well defined in each
implementation. This allows linkages between the code of one
compiler and another--an important real world consideration. Often
the argument passing is not even left up the compiler: the CPU
designer defines external linkage protocols and all compilers for
that CPU. Internal linkages, in C that would mean calling a static
function, can follow alternate protocols but often don't except for
optimising compilers.


[ Obnoxious '#' quoting character changed to '>'. ]
[ Obnoxious long lines re-wrapped. ]

(Context: the code in question passed a struct { int i; int j; } to
printf with a format string specifying two int arguments; it happened
to print the i and j members of the struct.)

First, what we discuss here is standard C. We recognize that
implementations have system-specific characteristics, but if we're
going to discuss non-portable code we will *at least* point out that
it's non-portable, and why it's non-portable. The code in question
invokes undefined behavior, and will almost certainly break on some
implementations. The task the code was trying to accomplish could
easily be achieved portably; even if it's a hack rather than a bug,
there's no advantage in using it. It's also an extremely fragile
technique. It might work for printf() but fail for a function that
doesn't take a fixed number of arguments, or, as you point out, it
might work for an external function but fail for a static function.
Imagine a program's behavior changing subtly because you add a
"static" keyword to a function definition. Imagine tracking down the
bug, assuming you even notice it. Now imagine avoiding such bugs by
writing portable code in the first place.

Second, "defined" means "documented". If you can cite the
system-specific documentation that states, or implies, that the code
is guaranteed to behave in the observed manner you *might* have a
point. The OP was using VC++. Was your statement based on the actual
VC++ documentation, or were you guessing? I can't tell, because you
didn't provide any hints as to *why* the OP's code was equivalent to

printf("i==%d i==%d \n",var.i,var.j,var.i);

You could have mentioned that excess arguments to printf() are ignored
(the standard actually specifies that). But most importantly, if you
intended to provide information that's specific to VC++, you should
have said so. This is comp.lang.c; unqualified statements made here
are assumed to refer to the standard language. In that context, your
answer was simply wrong. This isn't even about redirecting the
discussion to a system-specific newsgroup; it's about making
statements that are misleading in the context of this one.

Just providing a literal answer to a poster's question is often not
helpful, as you've demonstrated. Your answer may (or may not) be
correct within the narrow confines of the OP's particular
implementation, but it could easily lead the OP to believe things that
simply aren't true. And now you're annoyed at the rest of us for
providing useful information rather than just providing a "correct"
but misleading answer to the question.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 14 '05 #22

P: n/a
Groovy hepcat Markus Moll was jivin' on Tue, 17 May 2005 14:19:35
+0200 in comp.lang.c.
Re: Strange behaviour of printf. See the code below and please tell
why it behaves in this way.'s a cool scene! Dig it!
DeltaOne wrote:
#include<stdio.h>
typedef struct test{
int i;
int j;
}test;

main(){
test var;
var.i=10;
var.j=20;

printf("i==%d i==%d \n",var,var.i);
return 1;
}

Compiler in VC++ and see that you get the output is i==10 i==20
VC++ ought to reject this code, as it is not valid C++. However, you're
asking in a C group about C code, so I assume you really want to compile
this as a C program. Then the compiler should warn for several reasons.


Nonsense! The code is legal (C90), as far as the compiler knows,
notwithstanding the non-portable return value of main(). The error is
in the use of a library function, not the syntactical correctness of
the code.
Firstly, as far as I know, implicit int declaration is discouraged even in
True. It is discouraged, but legal in C90. Had he a C99
implementation, he would have recieved a diagnostic, as this is
illegal in C99.
C. Secondly, the compiler will notice that the arguments of printf don't
match the format string.
No, the compiler will do no such thing. Some compilers do. The one
the OP is using doesn't. They are not required to do so. This is
simply a case of undefined behaviour. Anything may happen, including
diagnosing the arguments passed to printf() or simply ignoring them
and quietly passing them.
This is also the reason for the observed
behaviour.
You're supplying a struct test, then an int. printf expects two ints.
Now accidentally your struct test is nothing but two ints (i and j).
Possibly. Probably. But even this is not guaranteed. Structures may
contain padding, so the output the OP could have got may be quite
different. The padding may even have formed a trap representation when
treated as an int (though that wouldn't happen with the implementation
he's using). Again anything may happen. There is no right or wrong
behaviour for cases like this.
These are printed.

GCC says:
7: warning: return type defaults to `int'
In function `main':
12: warning: int format, test arg (arg 2)


Yes, gcc catches this. VC++ does not.

--

Dig the even newer still, yet more improved, sig!

http://alphalink.com.au/~phaywood/
"Ain't I'm a dog?" - Ronny Self, Ain't I'm a Dog, written by G. Sherry & W. Walker.
I know it's not "technically correct" English; but since when was rock & roll "technically correct"?
Nov 14 '05 #23

P: n/a
# First, what we discuss

Do you always use the royal plural? You aren't speaking for me.
Nor are you speaking on behalf of the nonexistent newsgroup moderator.

# implementations. The task the code was trying to accomplish could
# easily be achieved portably; even if it's a hack rather than a bug,

The code had no task. It was a result the original poster didn't
understand but anybody with compiler writing experience can understand.

# "static" keyword to a function definition. Imagine tracking down the
# bug, assuming you even notice it. Now imagine avoiding such bugs by
# writing portable code in the first place.

You're in self-righteous lather over nothing. Nobody has said passing
a struct by value where individual ints are expected is good idea.

Still doesn't mean you can't understand what happens when then happens.

# point. The OP was using VC++. Was your statement based on the actual
# VC++ documentation, or were you guessing? I can't tell, because you
# didn't provide any hints as to *why* the OP's code was equivalent to
#
# printf("i==%d i==%d \n",var.i,var.j,var.i);

Because callee doesn't know the argument list length, it needs the first
argument location and computes later arguments from that. Nearly all CPUs
push arguments back to front on a stack that decrements on push; the final
stack pointer points at or near the first argument with successive
arguments at increasing stack addresses. Because the struct needs no
padding and fields are at ascending addresses, pushing the struct is
the same as push the arguments in reverse order.

Loading the top few words of the argument list in registers
doesn't substantially change this.

A less popular way today is to allocate the argument vector elsewhere in own,
loc, or heap storage, fill it in, and pass in the argument vector address
in. For interoperability and simplicity, such argument vectors are laid
out in ascending address for successive arguments. The struct in such
a vector would be the same as two successive ints.

What would cause problems is a machine that pushes back to front with
a stack that increments on push. But such machines are rare today.

# (the standard actually specifies that). But most importantly, if you
# intended to provide information that's specific to VC++, you should

It's not specific to VC++ or gcc or Fortran or Pascal. It's based on
experience with the kinds of machines that are actually in use today.
If you don't have that much experience, would you even understand the
explanation?

# the rest of us for

Stop using the royal plural. Speak for yourself. Let others speak
for themselves.

I have my own opinions on passing structs, but since those weren't
asked for, why present them?

--
SM Ryan http://www.rawbw.com/~wyrmwif/
One of the drawbacks of being a martyr is that you have to die.
Nov 14 '05 #24

P: n/a
SM Ryan wrote:
cat main.c #include<stdio.h>

typedef struct test{
int i;
int j;
} test;

int main(int argc, char* argv[]) {
test var = {10, 20};
int k = 33;

printf("i = %d\ti = %d\n", var, k);
return 1;
}
gcc -Wall -std=c99 -pedantic -o main main.c main.c: In function `main':
main.c:12: warning: int format, test arg (arg 2) ./main i = 10 i = 20
When you pass a struct by value, all the fields of the struct
are placed in the argument list in order, along with any padding.


Bingo!
Nov 14 '05 #25

P: n/a
I've made my point. I'm not going to waste any more time on this.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 14 '05 #26

P: n/a
"E. Robert Tisdale" <E.**************@jpl.nasa.gov> writes:
SM Ryan wrote:

[snip]
When you pass a struct by value, all the fields of the struct
are placed in the argument list in order, along with any padding.


Bingo!


If ERT means to imply that this is implied by the language definition,
he is mistaken.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 14 '05 #27

P: n/a
SM Ryan <wy*****@tango-sierra-oscar-foxtrot-tango.fake.org> wrote:
First, what we discuss
Do you always use the royal plural? You aren't speaking for me.
Are you being rude, or really so stupid? Keith is speaking for me,
and for those that don't answer you, because they have killfiled you.
Nor are you speaking on behalf of the nonexistent newsgroup moderator.


At present he's on leave (or something). If he were here, you would
have been called an vqvbg and moderated out of here long ago.

[Why isn't Dan Pop helpful anymore? I think I've seen his posts this year.]

[snip]

I'm not going to comment on any of your insane arguments (Keith
has said enough anyway). If you can't understand the difference
between a "guaranteed behaviour" and a "coincidence" then your
place is in the audience.

--
Stan Tobias
mailx `echo si***@FamOuS.BedBuG.pAlS.INVALID | sed s/[[:upper:]]//g`
Nov 14 '05 #28

P: n/a
"S.Tobias" <si***@FamOuS.BedBuG.pAlS.INVALID> wrote:
# SM Ryan <wy*****@tango-sierra-oscar-foxtrot-tango.fake.org> wrote:
#
# > > First, what we discuss
#
# > Do you always use the royal plural? You aren't speaking for me.
#
# Are you being rude, or really so stupid? Keith is speaking for me,

Are you being dense or really obnoxious? comp.lang.c is not a moderated newsgroup.
He can speak for his clique if he has verified they all agree with him. As to
assuming he speaks for everyone--programmers are supposed to know about the
dangers of hidden assumptions.

# At present he's on leave (or something). If he were here, you would
# have been called an vqvbg and moderated out of here long ago.

There is no moderator. Live with it. You're free to restrict your browsing
to comp.lang.c.moderated.

For the last 15 years comp.lang.c has decayed from a useful newsgroup
to a nasty little clique that is perfectly willing to engage in off topic
soliquies amongst themselves but goes ballistic whenever a lost newcomer
strays in with a real question. And most of the off topic rants are premature
kneejerk responses which betray the clique's agenda: any reference to a POSIX
function which is not ANS C is automatically ranted even with the issue is
not the semantics of function but the syntax of the call and surrounding code.
# I'm not going to comment on any of your insane arguments (Keith
# has said enough anyway). If you can't understand the difference
# between a "guaranteed behaviour" and a "coincidence" then your
# place is in the audience.

Don't lecture your betters.

--
SM Ryan http://www.rawbw.com/~wyrmwif/
JUSTICE!
Justice is dead.
Nov 14 '05 #29

P: n/a
SM Ryan <wy*****@tango-sierra-oscar-foxtrot-tango.fake.org> wrote:
"S.Tobias" <si***@FamOuS.BedBuG.pAlS.INVALID> wrote:
SM Ryan <wy*****@tango-sierra-oscar-foxtrot-tango.fake.org> wrote:
Keith Thompson wrote:
> First, what we discuss
Do you always use the royal plural? You aren't speaking for me.


Are you being rude, or really so stupid? Keith is speaking for me,

Are you being dense
Dense? I'm trying to give you a hint. Two is not enough for "we"
for you? Fine. Google for: "group:comp.lang.c what we discuss".
Not enough yet?
or really obnoxious?
What did I say "obnoxious" last time?
comp.lang.c is not a moderated newsgroup.
So what? Do you piss in the park? Do you fart at dinner? Do you
whistle in the church? Need more hints?
He can speak for his clique
Clique??? Who? Where?
if he has verified they all agree with him.
I'm sure Keith knows what he is saying.

There is no moderator. Live with it. You're free to restrict your browsing
to comp.lang.c.moderated.
Yesss...

For the last 15 years comp.lang.c has decayed from a useful newsgroup
to a nasty little clique that is perfectly willing to engage in off topic
soliquies amongst themselves but goes ballistic whenever a lost newcomer
strays in with a real question. And most of the off topic rants are premature
kneejerk responses which betray the clique's agenda: any reference to a POSIX
function which is not ANS C is automatically ranted even with the issue is
not the semantics of function but the syntax of the call and surrounding code.
Yeah, yeah... and they're after your dog, too, you know... <sip>...
those bandits don't even allow you to have l337 quotation characters,
either <sip>... too bad... ya know... right... <sip>... life is
darn tough... really darn tough... Let's have another pint...

Don't lecture your betters.


I have enough brains to know whom not to listen to. Especially
not to those "betters" that teach their betters.

--
Stan Tobias
mailx `echo si***@FamOuS.BedBuG.pAlS.INVALID | sed s/[[:upper:]]//g`
Nov 14 '05 #30

P: n/a
"S.Tobias" wrote:
SM Ryan <wy*****@tango-sierra-oscar-foxtrot-tango.fake.org> wrote:
.... snip ...
Don't lecture your betters.


I have enough brains to know whom not to listen to. Especially
not to those "betters" that teach their betters.


I think the time for this has come:

+-------------------+ .:\:\:/:/:.
| PLEASE DO NOT | :.:\:\:/:/:.:
| FEED THE TROLLS | :=.' - - '.=:
| | '=(\ 9 9 /)='
| Thank you, | ( (_) )
| Management | /`-vvv-'\
+-------------------+ / \
| | @@@ / /|,,,,,|\ \
| | @@@ /_// /^\ \\_\
@x@@x@ | | |/ WW( ( ) )WW
\||||/ | | \| __\,,\ /,,/__
\||/ | | | jgs (______Y______)
/\/\/\/\/\/\/\/\//\/\\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
================================================== ============

--
"If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson
Nov 14 '05 #31

P: n/a
CBFalconer <cb********@yahoo.com> wrote:
"S.Tobias" wrote:
SM Ryan <wy*****@tango-sierra-oscar-foxtrot-tango.fake.org> wrote:
[snip all]
| PLEASE DO NOT | :.:\:\:/:/:.:
| FEED THE TROLLS | :=.' - - '.=:


Whomever you had in mind, I am sorry I got unnerved.
I'll try to keep more quiet next time.
I'm quitting right here.

--
Stan Tobias
mailx `echo si***@FamOuS.BedBuG.pAlS.INVALID | sed s/[[:upper:]]//g`
Nov 14 '05 #32

This discussion thread is closed

Replies have been disabled for this discussion.