Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Q: Local variables initialization shortcut.

Reply
Thread Tools

Q: Local variables initialization shortcut.

 
 
Jens Thoms Toerring
Guest
Posts: n/a
 
      06-02-2012
Jean-Christophe <(E-Mail Removed)> wrote:
> On 2 juin, 19:39, (E-Mail Removed) (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 ___ http://www.velocityreviews.com/forums/(E-Mail Removed)
\__________________________ http://toerring.de
 
Reply With Quote
 
 
 
 
Eric Sosman
Guest
Posts: n/a
 
      06-02-2012
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
(E-Mail Removed)d
 
Reply With Quote
 
 
 
 
Keith Thompson
Guest
Posts: n/a
 
      06-02-2012
Jean-Christophe <(E-Mail Removed)> writes:
> On 2 juin, 19:39, (E-Mail Removed) (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) (E-Mail Removed) <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"
 
Reply With Quote
 
Keith Thompson
Guest
Posts: n/a
 
      06-02-2012
Jean-Christophe <(E-Mail Removed)> writes:
> On 2 juin, 16:59, James Kuyper <(E-Mail Removed)> wrote:
>> > Since these variables are located in the stack,
>> > is there a way to FORCE the compiler to align them,
>> > using a compiler directive or something ?

>
>> Yes - but it's not a compiler directive

>
> So it's "No" since it's not a compiler directive.


It's "Yes" since it's an "or something".

--
Keith Thompson (The_Other_Keith) (E-Mail Removed) <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"
 
Reply With Quote
 
Jens Thoms Toerring
Guest
Posts: n/a
 
      06-02-2012
Eric Sosman <(E-Mail Removed)> 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 ___ (E-Mail Removed)
\__________________________ http://toerring.de
 
Reply With Quote
 
Jean-Christophe
Guest
Posts: n/a
 
      06-03-2012
On 2 juin, 23:18, (E-Mail Removed) (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 )
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.

 
Reply With Quote
 
Jean-Christophe
Guest
Posts: n/a
 
      06-03-2012
On 2 juin, 23:38, Eric Sosman <(E-Mail Removed)> 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.
 
Reply With Quote
 
Malcolm McLean
Guest
Posts: n/a
 
      06-03-2012
בתאריך יום שבת,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 whatformat. 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.
 
Reply With Quote
 
Noob
Guest
Posts: n/a
 
      06-05-2012
David Brown wrote:

> This is where "stuct" would be useful...


"stuct in the middle with you" ?
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
initialization order of function local static variables Severin Ecker C++ 9 03-11-2010 11:41 PM
local static variables' default initialization auspicious C++ 0 09-25-2008 10:02 PM
Can local function access local variables in main program? Sullivan WxPyQtKinter Python 10 11-08-2007 02:51 PM
different handling of local variables and instance variables when undefined Tammo Tjarks Ruby 2 09-13-2007 06:29 PM
Local variables initialization Michal Kwiatkowski Python 5 02-27-2006 02:56 AM



Advertisments