which it is
applied may change alone, meaning without an explicit action of the
program flow. This is the case with an input port, or with a variable
updated by an interrupt function. The effect of such a directive is to stop
the compiler optimizing the accesses to such a variable. In the follow-
ing example:
char PORTA;
PORTA = 1; /*create a short pulse on bit 0 */
PORTA = 0;
The first assigment will be optimized out by the compiler as the PORTA
variable is supposed to be a plain memory location which is not used
between the two assigments. If such a variable is matching a physical
output port, it must be declared as a volatile object:
volatile char PORTA;
A modifier applies to the current element being defined. When applied
to a pointer, a modifier may affect the pointer itself, or the pointed
object, depending on its position in the declaration. If the modifier is
Modifiers
© Copyright 2003 by COSMIC Software
Declarations 3-7 placed before the * character, it affects the pointed object. If the modi-
fier is place after the * character, it affects the pointer.
const char *pc; /* pointer to a constant char */
pc = qc; /* OK */
*pc = 0; /* ERROR */
The first assignment modifies the pointer itself and is allowed. The sec-
ond assignment tries to modify the pointed const object, and is then not
allowed.
char * const pc;/* constant pointer to a char */
pc = qc; /* ERROR */
*pc = 0; /* OK */
The first assignment tries to modify a const pointer and is then not
allowed. The second assignment modifies the pointed object and is
allowed.
const char * const pc;
The pc object is declared as a const pointer to a const object, so no
assignment to the pointer itself or to the pointed object will be allowed.
Such an object probably needs to be initialized within the declaration to
have any useful meaning for the program.
The compiler also implements special modifiers whose usage depends
on the target processor:
The @packed modifier is used when the target processor requests an
even alignment on word or larger objects, in order to stop the alignment
for the specified object, assuming that unaligned accesses are still sup-
ported by the processor. It can also be used on a function definition to
stop alignment on local variables thus shortening the local size.
The @nostack modifier is used to allocate a function stack frame
(locals and arguments) in static memory instead of using the physical
stack. This feature is interesting for small processors where the physical
stack is not easily accessible. In such a case, the memory used for those
local areas is allocated and optimized by the linker in order to consume
the smallest amount of memory as possible.
Structures
3-8 Declarations © Copyright 2003 by COSMIC Software
3
Structures
A structure is declared by declaring all of its fields. They are grouped
between curly braces and are preceded by the keyword struct. A struc-
ture, as a type, may be named to be reused later. This feature avoids
repeating the full content of the structure. Such a name is called a tag
name and is placed between the keyword struct and the opening curly
brace.
struct { /* unnamed structure */
int a; /* first field is an int */
char b; /* second is a char */
long c; /* third is a long */
}
This set will fill the field of the global declaration syntax. There
is no modification of the field.
struct node { /* named structure */
int value;
struct node *left;
struct node *right;
} n1, n2;
declares two structures of type node. A reference to a not yet com-
pleted structure is possible as long as it is used to define pointers. Once
a tag name has been associated to a structure, any further declaration
does not need to repeat the structure content:
struct node n3, n4;
A structure initialization will be written by an equal sign = followed by
a list of values placed between curly braces, and separated by commas.
Each field is initialized by the corresponding value, converted to the
corresponding type.
struct {
char a;
int b;
long c;
} st = {1, 2, 3};
Structures
© Copyright 2003 by COSMIC Software
Declarations 3-9 field
a is initialized with value 1
field
b is initialized with value 2
field
c is initialized with value 3
If the initialization list contains less values than structure fields, the
missing fields are initialized to zero.
A bitfield is declared by suffixing the field name with a colon followed
by the number of bits used by the bitfield. A bitfield can be declared in
any integer type (the ANSI standard allows only types int and unsigned
int for bitfileds. The other possible types are extensions allowed by the
Cosmic compiler, and by most compilers targetting microcontrolers).
The reference type used is considered to be the allocation unit, meaning
that an integer of that type is open and filled until there is no more space
available. Any bitfield overlapping an allocation unit boundary is allo-
cated in a new integer.
struct {
char a:4;
char b:3;
char c:2;
}
This structure defines 3 bitfields based on a char allocation unit. A first
char is open and bitfields a and
Continue reading on your phone by scaning this QR Code
Tip: The current page has been bookmarked automatically. If you wish to continue reading later, just open the
Dertz Homepage, and click on the 'continue reading' link at the bottom of the page.