CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

How to Declare an Uninitialised Variable
Goto page Previous  1, 2, 3  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Ttelmah



Joined: 11 Mar 2010
Posts: 19587

View user's profile Send private message

PostPosted: Thu Jun 14, 2012 1:38 am     Reply with quote

Sorry, but _incorrect_. The manual, and the C 'bible' are quite explicit.

First, look at the 'static' entry in the manual. Says:

"Variable is globally active and initialized to 0.". Note the 'initialized'.

Then read K&R. "The C programming language":

"In the absence of explicit initialisation, external and static variables are guaranteed to be initialised to zero, automatic and register variables are uninitialised, and have undefined (i.e. garbage) initial values."

C, is quite explicit, that variables that are _not_ initialised explicitly, and are not static or extern, are left uninitialised. CCS has followed this to the letter.

Best Wishes
lukeevanslx



Joined: 11 Jun 2012
Posts: 14

View user's profile Send private message

PostPosted: Thu Jun 14, 2012 1:54 am     Reply with quote

Ttelmah wrote:


C, is quite explicit, that variables that are _not_ initialised explicitly, and are not static or extern, are left uninitialised.



No, it does not say that. That has been inferred. What it says is that 'static' variables are initialised. What is done with uninitialised static variables is not specified.

The only variables which are guaranteed as unitialised are automatic and register. That is what it explicitly says.

These location types do not help us in our specific application.

What's needed is to have the explicit behaviour documented and preferrably supported with a non-standard directive, or to check your .lst files.
Ttelmah



Joined: 11 Mar 2010
Posts: 19587

View user's profile Send private message

PostPosted: Thu Jun 14, 2012 3:40 am     Reply with quote

As I said:

"automatic and register variables are uninitialised"
There is no such thing as an 'uninitialised static variable'.

Pretty explicit.
lukeevanslx



Joined: 11 Jun 2012
Posts: 14

View user's profile Send private message

PostPosted: Thu Jun 14, 2012 4:04 am     Reply with quote

You are right.
My bad. It is what is done with static variables that are not explicitly initialised that is not explicitly specified. And that is the whole point of the thread.
Ttelmah



Joined: 11 Mar 2010
Posts: 19587

View user's profile Send private message

PostPosted: Thu Jun 14, 2012 4:24 am     Reply with quote

lukeevanslx wrote:
You are right.
My bad. It is what is done with static variables that are not explicitly initialised that is not explicitly specified. And that is the whole point of the thread.


Yes, it is. _Static_ variables, are _always_ initialised to zero. This is in the lines both from K&R, and the CCS manual. There is no such thing as an 'uninitialised static variable'....

I think you may be misunderstanding variable 'types'.

Just declare _global_ variables. These are 'automatic' variables, who's existence is global to the whole program. They are therefore _defined_ as uninitialised unless you specifically initialise them. Since they are 'global', they remain allocated for the entire life of the program, as opposed to losing their memory allocation when a routine exits.

The 'point' about static variables, is that they are initialised _once_ when the program starts, use stationary memory allocation, and are _not_ therefore re-iniitialised when a function is called a second time, so can be used to keep values from one call to another. Their 'name' though only has existence in the routine defining them, rather than global variables who's names remain defined in all routines.

Best Wishes
temtronic



Joined: 01 Jul 2010
Posts: 9269
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Thu Jun 14, 2012 4:29 am     Reply with quote

Ok, I'm at a loss to understand WHY you would want to have an uninitialised variable.(the original thread.)
It seems really,really BAD programming to NOT set variables to a KNOWN condition before 'main' runs unless you want some kind of random data.Perhaps someone can explain why you want this ?
Getting old but always willing to learn!
Ttelmah



Joined: 11 Mar 2010
Posts: 19587

View user's profile Send private message

PostPosted: Thu Jun 14, 2012 4:56 am     Reply with quote

The key for myself (one of the people who uses this), is to initialise them _myself_, only when the start conditions warrant it.

You use 'restart_cause', and check for this being a 'power up', and then call your own code to initialise all variables the way you want them. However if the cause is 'watchdog timeout', you can carry on with the code, without re-initialising, and hopefully retain values. Similarly one of the other posters tests for the cause being a press of the reset button, not 'power up', and can then use this to allow code to continue.
Yes, you _must_ at some point initialise the variables, _but_ it is quite common to not want this to happen if the code is restarting, but the processor has not switched off.

Best Wishes
FvM



Joined: 27 Aug 2008
Posts: 2337
Location: Germany

View user's profile Send private message

PostPosted: Thu Jun 14, 2012 9:24 am     Reply with quote

A typical motivation for uninitialized global variables is to have them keep the value across a processor reset.

With CCS C, all regular global variables are uninitialized unless you specify a #zero_ram "preprocessor" command. This is in contrast to the behaviour of most (all?) other C-compilers that zero global variables at startup.

Because variables with arbitrary initial value are a popular cause of erratic application behaviour, I would normally suggest to use the #zero_ram command. If you want some variables to keep it's value across resets, you have to refer to explicite initialization of all variables that need it.

Alternatively, you can keep using #zero_ram, #reserve a RAM range and access the data in it through pointers. This is also the typical method with a regular C-compiler that doesn't provide specific means for uninitialized variables.

P.S.: One more point
Quote:
Just declare _global_ variables. These are 'automatic' variables, who's existence is global to the whole program. They are therefore _defined_ as uninitialised unless you specifically initialise them. Since they are 'global', they remain allocated for the entire life of the program, as opposed to losing their memory allocation when a routine exits.

After reviewing K&R, I think there's a misunderstanding. Globally declared variables outside a block belong to the storage class extern and have to be cleared at startup. Automatic variables according to K&R are variables inside a block, e.g. a function. The static storage class specifier is intended to declare initialized (and persistent during program execution) variables inside a block.


Last edited by FvM on Thu Jun 14, 2012 11:56 am; edited 1 time in total
asmboy



Joined: 20 Nov 2007
Posts: 2128
Location: albany ny

View user's profile Send private message AIM Address

PostPosted: Thu Jun 14, 2012 9:54 am     Reply with quote

Quote:

keep the value across a processor reset.


a practical use of this feature that i employ:
1- Pic is controlling a piece of small rotating medical research machinery
2- there is intialization of the external system
3- there is a watchdog running for safety
4- several of these designs run on 16C parts w/o eeprom
5- i use a flag variable byte that has several bit map flags in it.
6- i use a WORD checksum that was inited itself with 0x5C5C + my flag byte value

7 -to check that the flag storage bye is valid i verify the checksum
and only then act on the flags if the value verifies as ok ( only one chance in 0xFFFF that it is actually not valid )

i assume that i should be detecting if there was a watchdog reset etc, AND i am sure there are a better ways to do it - but this is deployed and nobody is complaining .
temtronic



Joined: 01 Jul 2010
Posts: 9269
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Fri Jun 15, 2012 6:27 am     Reply with quote

ok...I see how and why you're using this 'feature' but it's a tad scary as a future version of the compiler might 'correct' the 'flaw'(not resetting variables when CPU is reset) and then it's back to recoding the programs to run with the newer compiler.
Ttelmah



Joined: 11 Mar 2010
Posts: 19587

View user's profile Send private message

PostPosted: Fri Jun 15, 2012 6:51 am     Reply with quote

temtronic wrote:
ok...I see how and why you're using this 'feature' but it's a tad scary as a future version of the compiler might 'correct' the 'flaw'(not resetting variables when CPU is reset) and then it's back to recoding the programs to run with the newer compiler.


Except that the C is quite explicit in requiring these variables _not_ to be initialised. It is in the ANSI spec as well.
Don't get confused by behaviour on the PC, where the memory is 'virtual memory', and is allocated when the program is called, and therefore zeroed. If you write ring 0 (driver) code for the PC, you rely on this as well.

Best Wishes
FvM



Joined: 27 Aug 2008
Posts: 2337
Location: Germany

View user's profile Send private message

PostPosted: Fri Jun 15, 2012 1:23 pm     Reply with quote

Quote:
Except that the C is quite explicit in requiring these variables _not_ to be initialised. It is in the ANSI spec as well.

No No. Global variables without explicite storage class attribute outside a block belong to the extern storage class and are zeroed by the RTL at startup. Every PC or embedded compiler is doing that - with the exception of CCS C.
Ttelmah



Joined: 11 Mar 2010
Posts: 19587

View user's profile Send private message

PostPosted: Fri Jun 15, 2012 3:12 pm     Reply with quote

C is quite explicit, that 'automatic' variables must not be initialised.
Hence standard variables declared in the 'main', must always be left uninitialised.
CCS allows the one 'extra', that global variables are also not initialised, but you don't have to use these.

You can refer to a variable declared in main, from any routine that is called by main, just as if it is global, by using the syntax main.variable_name.
This is why I originally said to declare the variables in the main, for which leaving them uninitialised is then a totally standard feature.

ANSI, does allow you _not_ to initialise the globals. It requires that initialisation of uninitialised globals _must_ be carried out by the loader, not the program itself. Hence you can replace this, and have the code not initialise the variables in certain circumstances. This is standard programming for PC applications that recover from a watchdog reboot.
Since CCS does not have a loader, but only the program, it is correct for it not to initialise these.

Best Wishes
FvM



Joined: 27 Aug 2008
Posts: 2337
Location: Germany

View user's profile Send private message

PostPosted: Sat Jun 16, 2012 4:03 am     Reply with quote

Quote:
C is quite explicit, that 'automatic' variables must not be initialised.
Hence standard variables declared in the 'main', must always be left uninitialised.

No doubt about. I was however referring to global defined variables as adressed in this statement:
Quote:
Just declare _global_ variables. These are 'automatic' variables, who's existence is global to the whole program. They are therefore _defined_ as uninitialised unless you specifically initialise them. Since they are 'global', they remain allocated for the entire life of the program, as opposed to losing their memory allocation when a routine exits.

Globally defined variables are external not automatic according to K&R, they have to be cleared.

To achieve the C standard behaviour with CCS C, #zero_ram must be specified. Otherwise, only variables with the static storage class attribute are initialized in CCS C, in the global as well as a local context.

I don't understand the loader point. In any embedded C compiler (except CCS C), the initialization of global and static variables is performed by the RTL startup code.

Regards,
Frank
Ttelmah



Joined: 11 Mar 2010
Posts: 19587

View user's profile Send private message

PostPosted: Sat Jun 16, 2012 4:27 am     Reply with quote

Read the section on initialisation in K&R.
It does _not_ require global's to be initialised. It only requires static variables to be initialised.
Initilalisation in K&R, is generally left as processor dependant, if not specified.
ANSI, changed things, requiring that global's if not explicitly initilalised, should be initialised, but explicitly required this to be done for global's before the program code itself, as part of the 'loader' (definition of this is left vague..). However provision exists in compiler's, to 're-write' this part. If you are running a PC, then you are almost certainly using C code, that relies on this. The BIOS on a PC, is 99% written in C, and quite large lumps of this rely on being able to relaunch sections, with their variables retained (I wrote some of them).
The same is true of quite a bit of the driver code used at low level inside the OS's as well.
The difference in CCS, is that the default behaviour is to not initialise. Effectively the standard would be for #ZERO_RAM to be the default behaviour, with an option to turn this off, while in CCS it is the opposite way round.

Best Wishes
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page Previous  1, 2, 3  Next
Page 2 of 3

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group