Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #21648 > unrolled thread
| Started by | Jean-Christophe <5.d@free.fr> |
|---|---|
| First post | 2012-06-02 02:49 -0700 |
| Last post | 2012-06-02 17:50 +0000 |
| Articles | 20 on this page of 61 — 17 participants |
Back to article view | Back to comp.lang.c
Q: Local variables initialization shortcut. Jean-Christophe <5.d@free.fr> - 2012-06-02 02:49 -0700
Re: Q: Local variables initialization shortcut. China Blue Max <chine.bleu@yahoo.com> - 2012-06-02 03:03 -0700
Re: Q: Local variables initialization shortcut. Jean-Christophe <5.d@free.fr> - 2012-06-02 03:17 -0700
Re: Q: Local variables initialization shortcut. jacob navia <jacob@spamsink.net> - 2012-06-02 12:06 +0200
Re: Q: Local variables initialization shortcut. Jean-Christophe <5.d@free.fr> - 2012-06-02 03:25 -0700
Re: Q: Local variables initialization shortcut. James Kuyper <jameskuyper@verizon.net> - 2012-06-02 10:59 -0400
Re: Q: Local variables initialization shortcut. Jean-Christophe <5.d@free.fr> - 2012-06-02 13:02 -0700
Re: Q: Local variables initialization shortcut. Keith Thompson <kst-u@mib.org> - 2012-06-02 14:51 -0700
Re: Q: Local variables initialization shortcut. Ian Collins <ian-news@hotmail.com> - 2012-06-02 22:10 +1200
Re: Q: Local variables initialization shortcut. jt@toerring.de (Jens Thoms Toerring) - 2012-06-02 10:31 +0000
Re: Q: Local variables initialization shortcut. Jean-Christophe <5.d@free.fr> - 2012-06-02 03:59 -0700
Re: Q: Local variables initialization shortcut. jt@toerring.de (Jens Thoms Toerring) - 2012-06-02 11:55 +0000
Re: Q: Local variables initialization shortcut. pete <pfiland@mindspring.com> - 2012-06-02 08:15 -0400
Re: Q: Local variables initialization shortcut. Jean-Christophe <5.d@free.fr> - 2012-06-02 05:37 -0700
Re: Q: Local variables initialization shortcut. jt@toerring.de (Jens Thoms Toerring) - 2012-06-02 13:35 +0000
Re: Q: Local variables initialization shortcut. Jean-Christophe <5.d@free.fr> - 2012-06-02 06:47 -0700
Re: Q: Local variables initialization shortcut. "BartC" <bc@freeuk.com> - 2012-06-02 15:08 +0100
Re: Q: Local variables initialization shortcut. Jean-Christophe <5.d@free.fr> - 2012-06-02 07:37 -0700
Re: Q: Local variables initialization shortcut. "BartC" <bc@freeuk.com> - 2012-06-02 16:17 +0100
Re: Q: Local variables initialization shortcut. "BartC" <bc@freeuk.com> - 2012-06-02 19:02 +0100
Re: Q: Local variables initialization shortcut. jt@toerring.de (Jens Thoms Toerring) - 2012-06-02 17:39 +0000
Re: Q: Local variables initialization shortcut. Eric Sosman <esosman@ieee-dot-org.invalid> - 2012-06-02 15:27 -0400
Re: Q: Local variables initialization shortcut. Jean-Christophe <5.d@free.fr> - 2012-06-02 12:58 -0700
Re: Q: Local variables initialization shortcut. Eric Sosman <esosman@ieee-dot-org.invalid> - 2012-06-02 16:15 -0400
Re: Q: Local variables initialization shortcut. David Brown <david.brown@hesbynett.no> - 2012-06-03 15:27 -0500
Re: Q: Local variables initialization shortcut. Noob <root@localhost> - 2012-06-05 09:12 +0200
Re: Q: Local variables initialization shortcut. David Brown <david@westcontrol.removethisbit.com> - 2012-06-05 09:21 +0200
Re: Q: Local variables initialization shortcut. Jean-Christophe <5.d@free.fr> - 2012-06-02 12:53 -0700
Re: Q: Local variables initialization shortcut. "BartC" <bc@freeuk.com> - 2012-06-02 21:16 +0100
Re: Q: Local variables initialization shortcut. jt@toerring.de (Jens Thoms Toerring) - 2012-06-02 21:18 +0000
Re: Q: Local variables initialization shortcut. Eric Sosman <esosman@ieee-dot-org.invalid> - 2012-06-02 17:38 -0400
Re: Q: Local variables initialization shortcut. jt@toerring.de (Jens Thoms Toerring) - 2012-06-02 22:15 +0000
Re: Q: Local variables initialization shortcut. Jean-Christophe <5.d@free.fr> - 2012-06-03 00:51 -0700
Re: Q: Local variables initialization shortcut. Malcolm McLean <malcolm.mclean5@btinternet.com> - 2012-06-03 11:46 -0700
Re: Q: Local variables initialization shortcut. Jean-Christophe <5.d@free.fr> - 2012-06-03 00:13 -0700
Re: Q: Local variables initialization shortcut. Keith Thompson <kst-u@mib.org> - 2012-06-02 14:50 -0700
Re: Q: Local variables initialization shortcut. David Brown <david.brown@hesbynett.no> - 2012-06-03 15:34 -0500
Re: Q: Local variables initialization shortcut. David Brown <david.brown@hesbynett.no> - 2012-06-03 15:25 -0500
Re: Q: Local variables initialization shortcut. Eric Sosman <esosman@ieee-dot-org.invalid> - 2012-06-02 08:46 -0400
Re: Q: Local variables initialization shortcut. Jean-Christophe <5.d@free.fr> - 2012-06-02 05:46 -0700
Re: Q: Local variables initialization shortcut. Jean-Christophe <5.d@free.fr> - 2012-06-02 05:53 -0700
Re: Q: Local variables initialization shortcut. Ike Naar <ike@sverige.freeshell.org> - 2012-06-02 17:08 +0000
Re: Q: Local variables initialization shortcut. "io_x" <a@b.c.invalid> - 2012-06-03 10:33 +0200
Re: Q: Local variables initialization shortcut. "io_x" <a@b.c.invalid> - 2012-06-03 11:32 +0200
Re: Q: Local variables initialization shortcut. pete <pfiland@mindspring.com> - 2012-06-02 08:03 -0400
Re: Q: Local variables initialization shortcut. Jean-Christophe <5.d@free.fr> - 2012-06-02 05:18 -0700
Re: Q: Local variables initialization shortcut. "io_x" <a@b.c.invalid> - 2012-06-03 10:32 +0200
Re: Q: Local variables initialization shortcut. "BartC" <bc@freeuk.com> - 2012-06-02 11:45 +0100
Re: Q: Local variables initialization shortcut. Jean-Christophe <5.d@free.fr> - 2012-06-02 04:17 -0700
Re: Q: Local variables initialization shortcut. "BartC" <bc@freeuk.com> - 2012-06-02 12:40 +0100
Re: Q: Local variables initialization shortcut. "BartC" <bc@freeuk.com> - 2012-06-02 12:51 +0100
Re: Q: Local variables initialization shortcut. Jean-Christophe <5.d@free.fr> - 2012-06-02 04:57 -0700
Re: Q: Local variables initialization shortcut. "BartC" <bc@freeuk.com> - 2012-06-02 14:00 +0100
Re: Q: Local variables initialization shortcut. Jean-Christophe <5.d@free.fr> - 2012-06-02 06:12 -0700
Re: Q: Local variables initialization shortcut. Eric Sosman <esosman@ieee-dot-org.invalid> - 2012-06-02 09:58 -0400
Re: Q: Local variables initialization shortcut. David Brown <david.brown@hesbynett.no> - 2012-06-03 15:41 -0500
Re: Q: Local variables initialization shortcut. Robert Wessel <robertwessel2@yahoo.com> - 2012-06-02 11:45 -0500
Re: Q: Local variables initialization shortcut. Noob <root@localhost> - 2012-06-02 16:05 +0200
Re: Q: Local variables initialization shortcut. Jean-Christophe <5.d@free.fr> - 2012-06-02 07:48 -0700
Re: Q: Local variables initialization shortcut. "BartC" <bc@freeuk.com> - 2012-06-02 18:31 +0100
Re: Q: Local variables initialization shortcut. jt@toerring.de (Jens Thoms Toerring) - 2012-06-02 17:50 +0000
Page 2 of 4 — ← Prev page 1 [2] 3 4 Next page →
| From | jt@toerring.de (Jens Thoms Toerring) |
|---|---|
| Date | 2012-06-02 17:39 +0000 |
| Message-ID | <a2v1eeFru9U1@mid.uni-berlin.de> |
| In reply to | #21676 |
Jean-Christophe <5.d@free.fr> wrote:
> What I had in mind was this :
> #include <stdio.h>
> double a,b;
> int main(void)
> {
> unsigned int ia = (unsigned int)&a;
> unsigned int ib = (unsigned int)&b;
> printf( "ib - ia = %u\r\n", ib - ia );
> printf( "ia - ib = %u\r\n", ia - ib );
> return 0;
> }
> Output :
> ib - ia = 8 // = sizeof(double)
> ia - ib = 4294967288 // 0xFFFFFFF8
Please note that also converting a pointer to an (unsigned)
int is not well-defined - e.g. an int could be too small
for hoding the value of a pointer. You might try uintptr_t
(an integer type capable of holding object pointers) instead
(but which is an optional type and requires c99). You could
also simply cast to char * (a cast that is guaranteed to
work) and you should get the same (or at least a comparable)
result
printf( "ib - ia = %lu\n",
( unsigned long ) ( ( char * ) &b - ( char * ) &a ) );
without having to convert the pointers to some integer type
(since the size of a char is 1 per definition). The only
possible catch here is that unsigned long could still be
too small to hold a difference between two pointers (and
using "%td" to have the difference between the two pointers
treated as a ptrdiff_t type suffers from the same problem).
BTW, I jut noticed something funny: the output of this program
#include <stdio.h>
double a, b;
int main( void )
{
double c, d;
printf( "global diff: %td\n", ( char * ) &a - ( char * ) &b );
printf( "local diff: %td\n", ( char * ) &c - ( char * ) &d );
return 0;
}
is
global diff: 8
local diff: -8
So the the order of the positions of the variables in memory
(at least on my machine and using gcc 4.6.1) is different for
local and global variables. While not terribly interesting it
could serve as an example that making assumption about the
memory layout of variables the compiler will use is at least
tricky;-)
> > considers appropriate. It would also be "correct" when
> > the result would always be 42.
> I got that !
> (Douglas Noel Adams, uh ?)
Got it all in one go;-)
Regards, Jens
--
\ Jens Thoms Toerring ___ jt@toerring.de
\__________________________ http://toerring.de
[toc] | [prev] | [next] | [standalone]
| From | Eric Sosman <esosman@ieee-dot-org.invalid> |
|---|---|
| Date | 2012-06-02 15:27 -0400 |
| Message-ID | <jqdpf2$pn4$1@dont-email.me> |
| In reply to | #21700 |
On 6/2/2012 1:39 PM, Jens Thoms Toerring wrote:
>[...]
> So the the order of the positions of the variables in memory
> (at least on my machine and using gcc 4.6.1) is different for
> local and global variables. While not terribly interesting it
> could serve as an example that making assumption about the
> memory layout of variables the compiler will use is at least
> tricky;-)
One implementation *alphabetized* global variables, apparently
during the link phase. I discovered this while trying to port
some code that assumed `double trouble, bubble;' would imply
`&trouble < &bubble', which turned out not to be the case ...
Specifically, the code was doing things like (paraphrased):
int checksum_start;
... data to be checksum-protected ...
int checksum_end;
for (int *p = &checksum_start; ++p < checksum_end; ) {
... accumulate checksum ...
}
When alphabetization put `checksum_end' *before* `checksum_start',
the fan was hit by the fertilizer.
--
Eric Sosman
esosman@ieee-dot-org.invalid
[toc] | [prev] | [next] | [standalone]
| From | Jean-Christophe <5.d@free.fr> |
|---|---|
| Date | 2012-06-02 12:58 -0700 |
| Message-ID | <777886e2-33c1-4604-af25-d79e29686a0d@n5g2000vbb.googlegroups.com> |
| In reply to | #21703 |
On 2 juin, 21:27, Eric Sosman <esos...@ieee-dot-org.invalid> wrote:
> One implementation *alphabetized* global variables, apparently
> during the link phase. I discovered this while trying to port
> some code that assumed `double trouble, bubble;' would imply
> `&trouble < &bubble', which turned out not to be the case ...
> Specifically, the code was doing things like (paraphrased):
> int checksum_start;
> ... data to be checksum-protected ...
> int checksum_end;
> for (int *p = &checksum_start; ++p < checksum_end; ) {
> ... accumulate checksum ...
> }
>
> When alphabetization put `checksum_end' *before* `checksum_start',
> the fan was hit by the fertilizer.
That's funny because some years ago
I implemented something like this
... in asm, so it worked pretty well.
[toc] | [prev] | [next] | [standalone]
| From | Eric Sosman <esosman@ieee-dot-org.invalid> |
|---|---|
| Date | 2012-06-02 16:15 -0400 |
| Message-ID | <jqds94$bpl$1@dont-email.me> |
| In reply to | #21710 |
On 6/2/2012 3:58 PM, Jean-Christophe wrote:
> On 2 juin, 21:27, Eric Sosman<esos...@ieee-dot-org.invalid> wrote:
>
>> One implementation *alphabetized* global variables, apparently
>> during the link phase. I discovered this while trying to port
>> some code that assumed `double trouble, bubble;' would imply
>> `&trouble< &bubble', which turned out not to be the case ...
>> Specifically, the code was doing things like (paraphrased):
>> int checksum_start;
>> ... data to be checksum-protected ...
>> int checksum_end;
>> for (int *p =&checksum_start; ++p< checksum_end; ) {
>> ... accumulate checksum ...
>> }
>>
>> When alphabetization put `checksum_end' *before* `checksum_start',
>> the fan was hit by the fertilizer.
>
> That's funny because some years ago
> I implemented something like this
> ... in asm, so it worked pretty well.
Okay, but what has that to do with C? If a construct has some
particular effect in an assembler, do you expect to get the same
outcome in C? If it has some particular effect in Java, do you
expect the same outcome in C? If it has some particular effect in
German, do you expect the same outcome in C?
Don't confuse the tool you're using with the tool you're not.
--
Eric Sosman
esosman@ieee-dot-org.invalid
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2012-06-03 15:27 -0500 |
| Message-ID | <3Z-dnSaG4I0gVVbSnZ2dnUVZ7rOdnZ2d@lyse.net> |
| In reply to | #21703 |
On Sat, 02 Jun 2012 15:27:25 -0400, Eric Sosman wrote:
> On 6/2/2012 1:39 PM, Jens Thoms Toerring wrote:
>>[...]
>> So the the order of the positions of the variables in memory (at least
>> on my machine and using gcc 4.6.1) is different for local and global
>> variables. While not terribly interesting it could serve as an example
>> that making assumption about the memory layout of variables the
>> compiler will use is at least tricky;-)
>
> One implementation *alphabetized* global variables, apparently
> during the link phase. I discovered this while trying to port some code
> that assumed `double trouble, bubble;' would imply `&trouble < &bubble',
> which turned out not to be the case ...
>
> Specifically, the code was doing things like (paraphrased):
>
> int checksum_start;
> ... data to be checksum-protected ... int checksum_end;
>
> for (int *p = &checksum_start; ++p < checksum_end; ) {
> ... accumulate checksum ...
> }
>
> When alphabetization put `checksum_end' *before* `checksum_start', the
> fan was hit by the fertilizer.
This is where "stuct" would be useful...
[toc] | [prev] | [next] | [standalone]
| From | Noob <root@localhost> |
|---|---|
| Date | 2012-06-05 09:12 +0200 |
| Message-ID | <4fcdb167$0$6481$426a74cc@news.free.fr> |
| In reply to | #21760 |
David Brown wrote: > This is where "stuct" would be useful... "stuct in the middle with you" ?
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david@westcontrol.removethisbit.com> |
|---|---|
| Date | 2012-06-05 09:21 +0200 |
| Message-ID | <TNSdnV0DJfPfKVDSnZ2dnUVZ7oqdnZ2d@lyse.net> |
| In reply to | #21856 |
On 05/06/2012 09:12, Noob wrote:
> David Brown wrote:
>
>> This is where "stuct" would be useful...
>
> "stuct in the middle with you" ?
It is the standard way of controlling the ordering of data:
#define stuct struct
stuct {
int checksum_start;
... data to be checksum protected
int checksum_end;
} checkedData;
Don't you use stucts for this sort of thing? :-)
[toc] | [prev] | [next] | [standalone]
| From | Jean-Christophe <5.d@free.fr> |
|---|---|
| Date | 2012-06-02 12:53 -0700 |
| Message-ID | <9c25c022-dab8-4e7e-ba8f-1227a6b34023@b1g2000vbb.googlegroups.com> |
| In reply to | #21700 |
On 2 juin, 19:39, j...@toerring.de (Jens Thoms Toerring) wrote:
> (...) BTW, I jut noticed something funny:
> the output of this program
> #include <stdio.h>
> double a, b;
> int main( void )
> { double c, d;
> printf( "global diff: %td\n", ( char * ) &a - ( char * ) &b );
> printf( "local diff: %td\n", ( char * ) &c - ( char * ) &d );
> return 0;
> }
> is
> global diff: 8
> local diff: -8
I understand that : the address allocation for global
variables increases from the starting address,
while for local variables allocated on the stack
the stack pointer is decreased for each new variable.
> the result would always be 42.
>> (Douglas Noel Adams, uh ?)
> Got it all in one go ;-)
Well, on MY computer the correct
value is 41.999999999999999999
[toc] | [prev] | [next] | [standalone]
| From | "BartC" <bc@freeuk.com> |
|---|---|
| Date | 2012-06-02 21:16 +0100 |
| Message-ID | <jqdsbc$c5d$1@dont-email.me> |
| In reply to | #21707 |
"Jean-Christophe" <5.d@free.fr> wrote in message
news:9c25c022-dab8-4e7e-ba8f-1227a6b34023@b1g2000vbb.googlegroups.com...
> On 2 juin, 19:39, j...@toerring.de (Jens Thoms Toerring) wrote:
>
>> (...) BTW, I jut noticed something funny:
>> the output of this program
>> #include <stdio.h>
>> double a, b;
>> int main( void )
>> { double c, d;
>> printf( "global diff: %td\n", ( char * ) &a - ( char * ) &b );
>> printf( "local diff: %td\n", ( char * ) &c - ( char * ) &d );
>> return 0;
>> }
>> is
>> global diff: 8
>> local diff: -8
>
> I understand that : the address allocation for global
> variables increases from the starting address,
> while for local variables allocated on the stack
> the stack pointer is decreased for each new variable.
I still don't think you appreciate that these things can be unpredictable
(because addresses aren't allocated at the instant the identifier is
encountered in the source). Try this much simpler test:
#include <stdio.h>
double three;
double four;
int main(void)
{
printf( "&three = %u\n", (unsigned int)&three);
printf( "&four = %u\n", (unsigned int)&four);
printf( "&four-&three = %d\n", (int)&four-(int)&three);
return 0;
}
Which do you think has the lower address, 'three' or 'four'? Of my four
compilers, two gave a difference of -8, and two of +8.
--
Bartc
[toc] | [prev] | [next] | [standalone]
| From | jt@toerring.de (Jens Thoms Toerring) |
|---|---|
| Date | 2012-06-02 21:18 +0000 |
| Message-ID | <a2ve8uFl0bU1@mid.uni-berlin.de> |
| In reply to | #21707 |
Jean-Christophe <5.d@free.fr> wrote:
> On 2 juin, 19:39, j...@toerring.de (Jens Thoms Toerring) wrote:
> > (...) BTW, I jut noticed something funny:
> > the output of this program
> > #include <stdio.h>
> > double a, b;
> > int main( void )
> > { double c, d;
> > printf( "global diff: %td\n", ( char * ) &a - ( char * ) &b );
> > printf( "local diff: %td\n", ( char * ) &c - ( char * ) &d );
> > return 0;
> > }
> > is
> > global diff: 8
> > local diff: -8
> I understand that : the address allocation for global
> variables increases from the starting address,
> while for local variables allocated on the stack
> the stack pointer is decreased for each new variable.
Let's say it fits your mental model of what's going on
under the hood. This is quite often correct but sometimes
also can lead on astray. Learning assembler before C has
for sure its advantages, e.g. pointers, which seem to con-
fuse quite a number of people at first, are something ob-
vious etc. The danger is that one finds a lot of things
that seem to have an easy explanation since there seem to
be an obvious fit to how one would do it in assembler and
is thus sometimes tempted to wrongly extrapolate from that
(or take it for the truth). Knowing assembler (and maybe
even how the linker works on a certain machine) can thus
be quite helpful to build a mental image of how things
probably are working, but one has to be careful not to
blindly assume that things really work exactly as one
would expect from that. Can be a bit painful going from
"I know exactly what the machine is doing" to "what are
the damnded rules for this strange behaviour in C";-)
In the end I found it more useful trying to avoid to look
at C through my "assembler goggles" and instead accept it
as something different, having its own rules that I had to
learn and that not always could be easily explained in terms
of what I knew from assembler (on the bery limited set of
architectures I learned it for). Admittedly, that can be
harder than with languages that are that far removed from
assembler that one has no idea at all anymore what might
be going on under the hood.
> > the result would always be 42.
> >> (Douglas Noel Adams, uh ?)
> > Got it all in one go ;-)
> Well, on MY computer the correct
> value is 41.999999999999999999
;-)
Regards, Jens
--
\ Jens Thoms Toerring ___ jt@toerring.de
\__________________________ http://toerring.de
[toc] | [prev] | [next] | [standalone]
| From | Eric Sosman <esosman@ieee-dot-org.invalid> |
|---|---|
| Date | 2012-06-02 17:38 -0400 |
| Message-ID | <jqe15h$90d$1@dont-email.me> |
| In reply to | #21716 |
On 6/2/2012 5:18 PM, Jens Thoms Toerring wrote:
> [...] Learning assembler before C has
> for sure its advantages, e.g. pointers, which seem to con-
> fuse quite a number of people at first, are something ob-
> vious etc. [...]
A bad effect of learning assembly languages before C is
that one is tempted to think "Pointers? Oh, I get it: They're
just addresses, and I already know about addresses."
What's wrong with thinking "Pointers are addresses?" Here's
an illustration: In an assembly setting you might be told that
the R1 register holds an address and be asked to test whether the
value R1 points to is zero. Are you ready to write the test? No,
you need to ask "What kind of value does R1 point at? A single
byte, a two-byte integer, an eight-byte floating-point number, or
what?"
You never need to ask such questions in C, because a pointer
is not a bare address: It is an address *and a type*. If you're
told that the variable R1 points somewhere and you're asked to
test whether the pointee is zero, you're all set: The type of R1
is known, hence the type it points at is known, and you have all
the information you need: `if (*R1 == 0)', and you're off to the
races (if R1 points to something that's not comparable to zero
the compiler will complain -- but in that case the "test for zero"
question made no sense in the first place).
It seems to me from some of the rather peculiar subtractions
he's attempted that Jean-Christophe may harbor this very confusion
between typed pointers and assembly-style "bare" addresses.
--
Eric Sosman
esosman@ieee-dot-org.invalid
[toc] | [prev] | [next] | [standalone]
| From | jt@toerring.de (Jens Thoms Toerring) |
|---|---|
| Date | 2012-06-02 22:15 +0000 |
| Message-ID | <a2vhkiFl0bU2@mid.uni-berlin.de> |
| In reply to | #21719 |
Eric Sosman <esosman@ieee-dot-org.invalid> wrote:
> On 6/2/2012 5:18 PM, Jens Thoms Toerring wrote:
> > [...] Learning assembler before C has
> > for sure its advantages, e.g. pointers, which seem to con-
> > fuse quite a number of people at first, are something ob-
> > vious etc. [...]
> A bad effect of learning assembly languages before C is
> that one is tempted to think "Pointers? Oh, I get it: They're
> just addresses, and I already know about addresses."
> What's wrong with thinking "Pointers are addresses?" Here's
> an illustration: In an assembly setting you might be told that
> the R1 register holds an address and be asked to test whether the
> value R1 points to is zero. Are you ready to write the test? No,
> you need to ask "What kind of value does R1 point at? A single
> byte, a two-byte integer, an eight-byte floating-point number, or
> what?"
> You never need to ask such questions in C, because a pointer
> is not a bare address: It is an address *and a type*. If you're
> told that the variable R1 points somewhere and you're asked to
> test whether the pointee is zero, you're all set: The type of R1
> is known, hence the type it points at is known, and you have all
> the information you need: `if (*R1 == 0)', and you're off to the
> races (if R1 points to something that's not comparable to zero
> the compiler will complain -- but in that case the "test for zero"
> question made no sense in the first place).
> It seems to me from some of the rather peculiar subtractions
> he's attempted that Jean-Christophe may harbor this very confusion
> between typed pointers and assembly-style "bare" addresses.
Yes, that could be one of things I had to unlearn the hard
way... C makes a lot of things much more simple and safer,
but it can take some time to learn what they are, how they
work and then to appreciate them in the end;-) To be honest,
for about the first 5 years of using C I was blissfully igno-
rant of a lot of potential problems in the code I wrote - I
was programming on an architecture were I knew the assembler,
I had studied how the linker works in detail etc. and there
were no real surprises - everything seemed to fit quite nicely
and I considered myself to be a quite competent programmer. And
then came the day when I had to port one of my programs to a
different architecture - you can guess the rest of the story...
After a lot of pain (and quite a bit of deflation of my self-
esteem;-) I started to learn that C isn't assembler in dis-
guise - and lurking in comp.lang.c for some of time hope-
fully helped to cure some of the worst of my stupid mis-
understandings;-)
Regards, Jens
--
\ Jens Thoms Toerring ___ jt@toerring.de
\__________________________ http://toerring.de
[toc] | [prev] | [next] | [standalone]
| From | Jean-Christophe <5.d@free.fr> |
|---|---|
| Date | 2012-06-03 00:51 -0700 |
| Message-ID | <042b7220-dbd0-4e91-9124-2846c2f6151f@m10g2000vbn.googlegroups.com> |
| In reply to | #21719 |
On 2 juin, 23:38, Eric Sosman <esos...@ieee-dot-org.invalid> wrote: > A bad effect of learning assembly languages before C is > that one is tempted to think "Pointers? Oh, I get it: > They're just addresses, and I already know about addresses." > What's wrong with thinking "Pointers are addresses?" Here's > an illustration: In an assembly setting you might be told that > the R1 register holds an address and be asked to test whether the > value R1 points to is zero. Are you ready to write the test? No, > you need to ask "What kind of value does R1 point at? A single > byte, a two-byte integer, an eight-byte floating-point number, or > what?" > You never need to ask such questions in C, because a pointer > is not a bare address: It is an address *and a type*. If you're > told that the variable R1 points somewhere and you're asked to > test whether the pointee is zero, you're all set: The type of R1 > is known, hence the type it points at is known, and you have all > the information you need: `if (*R1 == 0)', and you're off to the > races (if R1 points to something that's not comparable to zero > the compiler will complain -- but in that case the "test for zero" > question made no sense in the first place). Yes, and if the type is integer (for instance) you don't have to know if it's big-endian or little-endian, if it's a float you don't have to know how it's coded, etc ... > It seems to me from some of the rather peculiar subtractions > he's attempted that Jean-Christophe may harbor this very confusion > between typed pointers and assembly-style "bare" addresses. The problem is not the fact that a difference of two pointers on a same data type has no sense, the problem is that I should not assume anything about the actual addresses of the variables. Now I understand why, thanks for helping me, but please, do not infer that I know nothing at all. Now, data type implementation does exist in asm, event if it's only in the head of the programmer. So if you're asked to test if an address points to a zero value, first of all you'll ask the question: test for what ? A bit (which one), a byte, an integer (how many bytes) a float (how is it coded) and so on.
[toc] | [prev] | [next] | [standalone]
| From | Malcolm McLean <malcolm.mclean5@btinternet.com> |
|---|---|
| Date | 2012-06-03 11:46 -0700 |
| Message-ID | <151c42a6-bc24-42e4-8d7d-8ee2d0b12292@googlegroups.com> |
| In reply to | #21719 |
בתאריך יום שבת, 2 ביוני 2012 22:38:52 UTC+1, מאת Eric Sosman: > > A bad effect of learning assembly languages before C is > that one is tempted to think "Pointers? Oh, I get it: They're > just addresses, and I already know about addresses." > > What's wrong with thinking "Pointers are addresses?" Here's > an illustration: In an assembly setting you might be told that > the R1 register holds an address and be asked to test whether the > value R1 points to is zero. Are you ready to write the test? No, > you need to ask "What kind of value does R1 point at? A single > byte, a two-byte integer, an eight-byte floating-point number, or > what?" > In assembly, if you're passed an address you need to know why you've been passed it, what data you are meant to read there or write there, and in what format. In C, you need to know why you've been passed a pointer, whether you're meant to read the data and or write to the buffer, and how big the buffer is. But pointers are tagged with the format. That's because C is a slightly higher level language than assembler. However often C pointers are void *s, in which case you have to know the format. The difference is very slight. Pointers cause problems for newbie programmers. Howwever I learned C after I had learnt assembler. So I said "*, what does that mean, it's clearly not a multiplication? Oh, it's the indirection operator." That was that. Pointers weren't a problem for me. malloc() was more of a leap, I'd always used fixed buffers in assembler. So I initially thought you could just ignore malloc(), it was an unimportant special extension.
[toc] | [prev] | [next] | [standalone]
| From | Jean-Christophe <5.d@free.fr> |
|---|---|
| Date | 2012-06-03 00:13 -0700 |
| Message-ID | <13c2a828-f7eb-4600-9137-616d96d5b5dc@3g2000vbx.googlegroups.com> |
| In reply to | #21716 |
On 2 juin, 23:18, j...@toerring.de (Jens Thoms Toerring) wrote: | I understand that : the address allocation for global | variables increases from the starting address, | while for local variables allocated on the stack | the stack pointer is decreased for each new variable. > Let's say it fits your mental model of what's going on > under the hood. This is quite often correct but sometimes > also can lead on astray. Learning assembler before C has > for sure its advantages, e.g. pointers, which seem to con- > fuse quite a number of people at first, are something ob- > vious etc. The danger is that one finds a lot of things > that seem to have an easy explanation since there seem to > be an obvious fit to how one would do it in assembler and > is thus sometimes tempted to wrongly extrapolate from that > (or take it for the truth). Knowing assembler (and maybe > even how the linker works on a certain machine) can thus > be quite helpful to build a mental image of how things > probably are working, but one has to be careful not to > blindly assume that things really work exactly as one > would expect from that. You're perfectly right. As an electronician I just can't avoid thinking that variables are stored somewhere in the hardware, (RAM, uP register, a buffer in some I/O chip, or even by the use of the capacitive property of a bus itself) and I perfectly understand why an IT guy will avoid such considerations. Abstraction of the hardware is needed for portability, but is the contrary of electronics. Anyway this is a reflex and I can't help it. Now, to take advantage of this, one needs a perfect knowledge of all the underlying, which is true for electronics w/ uP I designed myself, but is not always true for an implementation of code on a PC. > Can be a bit painful going from > "I know exactly what the machine is doing" to "what are > the damnded rules for this strange behaviour in C";-) > In the end I found it more useful trying to avoid to look > at C through my "assembler goggles" and instead accept it > as something different, having its own rules that I had to > learn and that not always could be easily explained in terms > of what I knew from assembler (on the bery limited set of > architectures I learned it for). I never said that knowing asm makes me a C programmer. I'm not *guessing* how C works, to try to use it like asm. (but I mix C & asm when it's convenient/needed/powerful) I just asked a question about an idea which turns out to be something better to forget : ok, no problem, thanks ! > Admittedly, that can be > harder than with languages that are that far removed from > assembler that one has no idea at all anymore what might > be going on under the hood. Arch ! I don't use these couternature things :o) I think C is a terrific language, because i can understand it, and use it efficiently. I know I have to avoid superimposing one field to another - otherwise I would't have posted here.
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2012-06-02 14:50 -0700 |
| Message-ID | <lnzk8lfknv.fsf@nuthaus.mib.org> |
| In reply to | #21707 |
Jean-Christophe <5.d@free.fr> writes:
> On 2 juin, 19:39, j...@toerring.de (Jens Thoms Toerring) wrote:
>
>> (...) BTW, I jut noticed something funny:
>> the output of this program
>> #include <stdio.h>
>> double a, b;
>> int main( void )
>> { double c, d;
>> printf( "global diff: %td\n", ( char * ) &a - ( char * ) &b );
>> printf( "local diff: %td\n", ( char * ) &c - ( char * ) &d );
>> return 0;
>> }
>> is
>> global diff: 8
>> local diff: -8
>
> I understand that : the address allocation for global
> variables increases from the starting address,
> while for local variables allocated on the stack
> the stack pointer is decreased for each new variable.
Global variables are allocated wherever the &^*%$ the implementation
decides to allocate them.
Local variables are allocated wherever the &^*%$ the implementation
decides to allocate them.
You should not make *any* assumptions about what any particular
implementation does.
Well, that might not *quite* be true, but it's very rare that it would
make any sense to make such assumptions. The result will be code that
can break badly when compiled on a different system, with a different
version of the same compiler, with the same compiler and different
optimization options, or with exactly the same options during a
different phase of the Moon.
You seem to have started with a certain set of assumptions based on the
behavior of one particular implementation, and are now trying to
understand systems that behave differently. You're likely to have
better luck by trying to understand just what the language does and does
not guarantee, and then understanding individual implementations in
terms of the choice they make within the limits imposed by the standard.
Don't worry about how variables are allocated; instead, write code that
will work regardless of how they're allocated.
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Will write code for food.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2012-06-03 15:34 -0500 |
| Message-ID | <3Z-dnSGG4I3sV1bSnZ2dnUVZ7rOdnZ2d@lyse.net> |
| In reply to | #21707 |
On Sat, 02 Jun 2012 12:53:01 -0700, Jean-Christophe wrote:
> On 2 juin, 19:39, j...@toerring.de (Jens Thoms Toerring) wrote:
>
>> (...) BTW, I jut noticed something funny: the output of this program
>> #include <stdio.h>
>> double a, b;
>> int main( void )
>> { double c, d;
>> printf( "global diff: %td\n", ( char * ) &a - ( char * ) &b );
>> printf( "local diff: %td\n", ( char * ) &c - ( char * ) &d );
>> return 0;
>> }
>> is
>> global diff: 8
>> local diff: -8
>
> I understand that : the address allocation for global variables
> increases from the starting address, while for local variables allocated
> on the stack the stack pointer is decreased for each new variable.
>
No, that's wrong in several ways.
It is very common that the memory layout on microcontrollers is to put
code and read-only data in flash. Then from the bottom of ram you get
the initialised data section, then the bss (uninitialised data,
automatically zeroed by the startup code). This is followed by the heap,
which grows upwards. The stack starts at the top of ram and grows
downwards.
The first mistake, however, is to assume this is always the case - it's
common, but not universal. There are even systems that split the stack
into a data stack and a return stack.
Secondly, although the stack generally decreases for each function call,
the common method is for the function prologue to allocate a frame size
and move the stack pointer down that size. But local data is allocated
upwards within that frame (well, mostly upwards - it is also re-used, and
passed around registers, and maybe re-arranged for greater efficiency).
Thirdly, within each section of data, items are often re-arranged. They
may be ordered by source module, alphabetically, by size, by "hot" and
"cold" usage, etc.
This is why the C standards are very clear - when you write "double a,
b;", you cannot say /anything/ about their relative positioning. They
may not even be allocated anywhere - even taking their address does not
necessarily force them to be allocated in ram if the compiler can figure
out a way to avoid it.
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2012-06-03 15:25 -0500 |
| Message-ID | <3Z-dnSeG4I2sVVbSnZ2dnUVZ7rOdnZ2d@lyse.net> |
| In reply to | #21667 |
On Sat, 02 Jun 2012 05:37:24 -0700, Jean-Christophe wrote: > All right then. > I understand I made the error of expanding my knowledge of > 'micro-controllers' C compilers to the 'PC' C compilers. Some things > won't work at all, and if they do it's even worse because it's just > luck. > > Thanks for taking time. If you are used to microcontrollers, then many of your assumptions are even worse (although it's fair enough to assume that a float with all zero bytes will be 0.0 - I can't think of any microcontroller which doesn't follow that, even though most don't follow IEEE exactly). It's quite simple - when you declare a local variable, you let the compiler decide. You have no guarantees as to whether the variables are put in memory at all, or will be held in registers, or will even be removed entirely by the optimiser. Even if they are put in memory, you know nothing about their ordering, nor their lifetimes, nor the sharing of data. In the world of microcontroller programming, no one bar a few beginners would use a compiler without enabling optimisation, because slower and bigger code means more expensive hardware. So while a few PC programmers might forget to enable optimisations, because speed and space are cheap on a PC, it should not happen in micrcontroller programming. And the only way you could think that the compiler would allocate the local variables "a, b, c..." blindly on the stack in the declared order is if you deliberately cripple your compiler by not enabling optimisation. Remember, premature optimisation is the root of all evil. Write your source code clearly and simply, and let the /compiler/ do the job of making good object code from it.
[toc] | [prev] | [next] | [standalone]
| From | Eric Sosman <esosman@ieee-dot-org.invalid> |
|---|---|
| Date | 2012-06-02 08:46 -0400 |
| Message-ID | <jqd1v4$cfo$1@dont-email.me> |
| In reply to | #21662 |
On 6/2/2012 7:55 AM, Jens Thoms Toerring wrote:
> Jean-Christophe<5.d@free.fr> wrote:
>> [...]
>>> '&z -&a' isn't legal - you can only subtract addresses
>>> of locations within a single object (e.g. an array),
>
>> I've done it many times and it always worked fine :
>> &a is the address of 'a' so it's its memory location.
>
> Well, you were lucky. The standard doesn't define what
> the result of subtracting pointers not within the same
> object is (or, in the case of arrays, one beyond the
> end of the array), so you are relying on whatever your
> compiler makes out of it. Some other compiler might
> give you a different result.
As a concrete example not requiring "exotic" hardware,
consider this fragment:
char buff[15];
typedef char Blob[7];
Blob *b1 = (Blob*) &buff[0];
Blob* b2 = (Blob*) &buff[8];
Now, what is `b2 - b1'? Pointer subtraction is supposed to
yield the number of pointed-at things between the two positions,
but how many 7-byte Blobs fit in the 8 bytes between their
starting positions? (For extra credit, change `8' to `1' in
the final line and answer again.)
In other words, the requirement is even stronger than Jens'
informal statement of it: You can only subtract pointers within
an array *of the pointed-at type*. The fact that `b1' and `b2'
both aim at spots within the array `buff' is not enough.
--
Eric Sosman
esosman@ieee-dot-org.invalid
[toc] | [prev] | [next] | [standalone]
| From | Jean-Christophe <5.d@free.fr> |
|---|---|
| Date | 2012-06-02 05:46 -0700 |
| Message-ID | <9d82f593-3b5e-4ad1-8d94-28c53177ecaf@b26g2000vbt.googlegroups.com> |
| In reply to | #21662 |
My apologies :
#include <stdio.h>
int main(void)
{
double a,b;
printf( "&b - &a = %2d\r\n", (int)( &b - &a ) );
printf( "&a - &b = %2d\r\n", (int)( &a - &b ) );
return 0;
}
&b - &a = 1
&a - &b = -1
[toc] | [prev] | [next] | [standalone]
Page 2 of 4 — ← Prev page 1 [2] 3 4 Next page →
Back to top | Article view | comp.lang.c
csiph-web