Q: Local variables initialization shortcut.

  • Thread starter Jean-Christophe
  • Start date
J

Jens Thoms Toerring

Jean-Christophe said:
On 2 juin, 19:39, (e-mail address 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. 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.
Well, on MY computer the correct
value is 41.999999999999999999

;-)
Regards, Jens
 
E

Eric Sosman

[...] 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.
 
K

Keith Thompson

Jean-Christophe said:
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.
 
J

Jens Thoms Toerring

Eric Sosman said:
[...] 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
 
J

Jean-Christophe

On 2 juin, 23:18, (e-mail address 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 :eek:)
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.
 
J

Jean-Christophe

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.
 
M

Malcolm McLean

בת×ריך ×™×•× ×©×‘×ª,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.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,079
Messages
2,570,574
Members
47,207
Latest member
HelenaCani

Latest Threads

Top