The one who can't C

H

Henning

Hi
Problems translating C-code to Basic.
Is unsigned char x; by default setting x to 0?

/Henning
 
J

Jens.Toerring

Henning said:
Problems translating C-code to Basic.
Is unsigned char x; by default setting x to 0?

It depends. If you define an automatic variable it's not initialized,
i.e. if you have something like this

int myfunction( char first_arg, int sec_arg )
{
unsigned char x;
...
}

then 'x' will have some random value (which might, just by luck, be 0).
When you port code you may still have to keep in mind that on some
platforms also such automatic variables get always initialized to 0
and if the program is relying on that non-standard feature you will
have to minimc this behavior.

If, on the other hand, 'x' is a global variable (i.e. one that isn't
defined within a function) then it will be initialized to 0.

Regards, Jens
 
H

Henning

--
Time is present only to prevent everything from happening at once.
Still it seems that everything happens at once.
Then there must be a bug in time.
To find the bug in time, isn't that what we all hope for.
It depends. If you define an automatic variable it's not initialized,
i.e. if you have something like this

int myfunction( char first_arg, int sec_arg )
{
unsigned char x;
...
}

then 'x' will have some random value (which might, just by luck, be 0).
When you port code you may still have to keep in mind that on some
platforms also such automatic variables get always initialized to 0
and if the program is relying on that non-standard feature you will
have to minimc this behavior.

If, on the other hand, 'x' is a global variable (i.e. one that isn't
defined within a function) then it will be initialized to 0.

Regards, Jens

The code is for an Atmel Risc MCU. I guess it is written in IAR's C4AVR.
The var's are defined within functions, so I guess I have to look closer
what is happening.
Thx for helping!
/Henning
 
K

Kelsey Bjarnason

[snips]

It depends. If you define an automatic variable it's not initialized,
i.e. if you have something like this

int myfunction( char first_arg, int sec_arg )
{
unsigned char x;
...
}

then 'x' will have some random value (which might, just by luck, be 0).

Maybe I'm missing something; is there any guarantee that x will have _any_
value whatsoever? Last I checked, attempting to take the value of an
uninitialized variable was undefined behaviour; the implementation is
perfectly within its rights to note that while there _will be_ an address
reserved for x, there may not have yet been one reserved, hence an attempt
to retrieve the value could merrily cause a crash.
 
R

Richard Bos

Kelsey Bjarnason said:
Maybe I'm missing something; is there any guarantee that x will have _any_
value whatsoever? Last I checked, attempting to take the value of an
uninitialized variable was undefined behaviour; the implementation is
perfectly within its rights to note that while there _will be_ an address
reserved for x, there may not have yet been one reserved, hence an attempt
to retrieve the value could merrily cause a crash.

For normal types, yes. However, all possible unsigned char
representations are required to be valid; there are no trap values in
unsigned char.

Richard
 
M

Mark F. Haigh

Henning said:
Hi
Problems translating C-code to Basic.
Is unsigned char x; by default setting x to 0?
<snip>

Perhaps you shouldn't be translating C to anything if you can't be
bothered to pick up a book on C and at least take a glance at it.


Mark F. Haigh
(e-mail address removed)
 
C

CBFalconer

Richard said:
For normal types, yes. However, all possible unsigned char
representations are required to be valid; there are no trap
values in unsigned char.

I doubt whether it occurs anywhere, but while your assertion of no
trap values is correct, there is no prohibition against other
means of detecting uninitialized values. For example, every byte
of storage could have an associated bit, reset on power-on, and
set when anything is written into the byte. Think of a parity
bit.

--
"I'm a war president. I make decisions here in the Oval Office
in foreign policy matters with war on my mind." - Bush.
"Churchill and Bush can both be considered wartime leaders, just
as Secretariat and Mr Ed were both horses." - James Rhodes.
"If I knew then what I know today, I would still have invaded
Iraq. It was the right decision" - G.W. Bush, 2004-08-02
 
P

pete

CBFalconer said:
I doubt whether it occurs anywhere, but while your assertion of no
trap values is correct, there is no prohibition against other
means of detecting uninitialized values. For example, every byte
of storage could have an associated bit, reset on power-on, and
set when anything is written into the byte.

That would be a trap representation.

I discussed this matter on comp.std.c once,
and my recollection was that the consensus was that
you could read unitialised bytes as unsigned char,
and from there it followed that reading an uninitialized
unsigned char variable was merely unspecified behavior.
 
K

Kelsey Bjarnason

[snips]

I discussed this matter on comp.std.c once,
and my recollection was that the consensus was that
you could read unitialised bytes as unsigned char,
and from there it followed that reading an uninitialized
unsigned char variable was merely unspecified behavior.

I'd question that. Try this:

unsigned char x,y;
x = y;

What prevents an implementation from simply not allocating space for y
until it has been initialized - which would mean the code goes zot?

This is a little different from say, using a pointer-to-byte to poke
around memory (video memory, say), as it's assumed that the target region
actually does exist and pointing the pointer at it initializes the pointer.

Then we have this:

double d[100];
unsigned char *s = (unsigned char *)&d;

Attempts to read *s, IMO, are at risk of a fault. Unlike the case of
poking about in video memory, etc, there's no assurance that the memory
for d has been allocated yet. Ponder the following in terms of the
generated pseudo assembler:

double d[100];
unsigned char *s = (unsigned char *)&d;
unsigned char c;
c = *s;
d[0] = 100.0;

..asm:

data d ?
data s ?
data c ?

addr1 <- addr d ; get address of d
mlock , 4 ; assign space for s
s <- addr1 ; store address of d in s
mlock [c],1 ; assign space for c
c <- (s) ; store value of *s in c
mlock [d], 100 * 8 ; assign space for d

That is, the system doesn't even _create_ a memory region for d until d is
initialized; the attempt to view the contents of that region via c = *s is
therefore trying to access memory which simply does not exist at all.

Is there a reason an implementation cannot work this way?
 
K

Keith Thompson

Kelsey Bjarnason said:
[snips]

I discussed this matter on comp.std.c once,
and my recollection was that the consensus was that
you could read unitialised bytes as unsigned char,
and from there it followed that reading an uninitialized
unsigned char variable was merely unspecified behavior.

I'd question that. Try this:

unsigned char x,y;
x = y;

What prevents an implementation from simply not allocating space for y
until it has been initialized - which would mean the code goes zot?

There are at least some limitations on this kind of thing. The
following is well-defined:

unsigned char x;
unsigned char *ptr = &x;
*ptr = 42;

x has to at least have a valid address before it's initialized.
Conceivably there needn't be any memory there, but if there isn't then
the memory has to be allocated *at that address* on the first
assignment.
 
C

CBFalconer

pete said:
That would be a trap representation.

I discussed this matter on comp.std.c once,
and my recollection was that the consensus was that
you could read unitialised bytes as unsigned char,
and from there it followed that reading an uninitialized
unsigned char variable was merely unspecified behavior.

As I said, and you snipped, think of a parity bit. Use of such
would give a 50% chance of a bad parity interrupt on reading any
byte in any manner in any language (including C) before
initialization. There is no reason the hardware should not have
the equivalent to detect reads from uninitialized storage. Such
hardware (parity) exists, and is quite common, although now
superseded by ECC in general. The standards were never intended
to preclude normal hardware.

--
"I'm a war president. I make decisions here in the Oval Office
in foreign policy matters with war on my mind." - Bush.
"Churchill and Bush can both be considered wartime leaders, just
as Secretariat and Mr Ed were both horses." - James Rhodes.
"If I knew then what I know today, I would still have invaded
Iraq. It was the right decision" - G.W. Bush, 2004-08-02
 
C

CBFalconer

pete said:
I know unsigned char as having only value bits.

A parity bit is an extra bit whose value is calculated from all
the other bits on write. It may describe odd or even parity. On
read, the parity is again calculated, and if it doesn't match a
hardware error has been detected. The result should be a system
interrupt.

Todays systems, when they have not been cheapened by eliminating
the feature, have replaced parity with ECC, which uses a set of
syndrome bits over a wider word to automatically correct one bit
errors, and detect multiple bit errors.

Since memory errors can be due to actual hardware failure, usually
repeatable, or external events (such as noise, or cosmic rays, or
alpha particles) that are not repeatable, it is foolish to
eliminate ECC checking on the memory system. Unfortunately the
majority of PCs sold today have done just that, and are inherently
untrustworthy.

All of this is transparent to the code using the memory. It
doesn't know it is there.

--
"I'm a war president. I make decisions here in the Oval Office
in foreign policy matters with war on my mind." - Bush.
"Churchill and Bush can both be considered wartime leaders, just
as Secretariat and Mr Ed were both horses." - James Rhodes.
"If I knew then what I know today, I would still have invaded
Iraq. It was the right decision" - G.W. Bush, 2004-08-02
 
C

Chris Torek

Kelsey Bjarnason said:
What prevents an implementation from simply not allocating space for [an object of type char and named]
y until it has been initialized ...

There are at least some limitations on this kind of thing. The
following is well-defined:

unsigned char x;
unsigned char *ptr = &x;
*ptr = 42;

x has to at least have a valid address before it's initialized.
Conceivably there needn't be any memory there, but if there isn't then
the memory has to be allocated *at that address* on the first
assignment.

Moreover, whether or not x (in Keith's code) or y is initialized,
two different pointers to the object must compare equal -- e.g.:

unsigned char *ptr = &x;
...
unsigned char *p2 = &x;
*ptr = 42;
unsigned char *p3 = &x; // assuming C99; or add a block
assert(ptr == &x);
assert(ptr == p2);
assert(ptr == p3);

I think it would be "challenging", to say the least, to make an
implementation work with lazy allocation.

Note also that it is legal to do things like:

struct with_holes x, y;
... /* set up all the fields in x */
memcpy(&y, &x, sizeof y);

where the (compiler-allocated) "holes" inside x are never initialized.
The memcpy() call accesses the uninitialized bytes within the object
x, copying their bitwise representations to the object y, even if
those bit patterns are "trap representations" when considered as
something other than "unsigned char"s.

Of course, there is no guaranteed way to produce holes -- bitfields
are perhaps the closest, using unnamed :0 fields to force alignment,
but even this operation is up to the implementation -- so if one
really wanted to work at a perverse implementation (for the
DeathStation 9000 perhaps), there might be some way to obey the
"letter of the law" of the Standard while violating the spirit. :)
 
R

RoSsIaCrIiLoIA

Hi
Problems translating C-code to Basic.
Is unsigned char x; by default setting x to 0?

if it is *out* every function or procedure (global):
YES you have to set x=0
if it is *in* any function or procedure
if there is
"static unsigned char x;" then you have to set x=0
else you can set x=0 or not;
 
N

Nick Keighley

RoSsIaCrIiLoIA said:
On Wed, 4 Aug 2004 01:20:12 +0200, "Henning"

<sigh> could you (RoSsIaCrIiLoIA) check your posts for correctness
*before*
you post them. Since I'm criticising someone this ensures this post
will
have at least one error...
if it is *out* every function or procedure (global):
YES you have to set x=0

if it outside any function (has file scope) then no you don't have to
initialise it as the compiler automatically initialises it to
0 (zero). Note C has no "procedures".
if it is *in* any function or procedure
if there is
"static unsigned char x;" then you have to set x=0
else you can set x=0 or not;

If it is inside a function and is marked "static" then no you don't
have to initialise it as the compiler automatically initialises it to
0 (zero). This
is only true the first time the function is called, any changes made
are permenent.

If it is inside a function and is not marked "static" then it is
automatic
variable and it is not initialised.
I would say if you see "unsigned char x;" set always x=0.

unless, that is, you want it initialised to something else...
 
R

RoSsIaCrIiLoIA

******************************************
^^^^^^^^^^^^^^^
******************************************
<sigh> could you (RoSsIaCrIiLoIA) check your posts for correctness
*before*
you post them. Since I'm criticising someone this ensures this post
will
have at least one error...


if it outside any function (has file scope) then no you don't have to
initialise it as the compiler automatically initialises it to
0 (zero).

you speak about *translation* from C to Basic? Right? In this contest
if you want to translate from C to Basic this:
unsigned char x;

that is *out* functions and procedure then YOU
(or the Basic compiler) have to initialise the 'x translation' in
Basic to 0. Because like you say "the [C] compiler automatically
initialises it to 0 (zero)." That is what I have said (but perhaps it
was not so clear, excuse me)
I don't know where Basic compiler initialises them to zero.
Note C has no "procedures".
unsigned a;
void proced(void){++a;}

Does it seem a function?
 

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

No members online now.

Forum statistics

Threads
474,262
Messages
2,571,059
Members
48,769
Latest member
Clifft

Latest Threads

Top