Initialization [ HP C/iX Reference Manual ] MPE/iX 5.0 Documentation
HP C/iX Reference Manual
Initialization
An initializer is the part of a declaration that provides the initial
values for the objects being declared.
Syntax
initializer ::=
assignment-expression
{initializer-list}
{initializer-list , }
initializer-list ::=
initializer
initializer-list , initializer
Description
A declarator may include an initializer that specifies the initial value
for the object whose identifier is being declared.
Objects with static storage duration are initialized at load time.
Objects with automatic storage duration are initialized at runtime when
entering the block that contains the definition of the object. An
initialization of such an object is similar to an assignment statement.
You can initialize a static object with a constant expression. You can
initialize a static pointer with the address of any previously declared
object of the appropriate type plus or minus a constant.
You can initialize an auto scalar object with an expression. The
expression is evaluated at run-time, and the resulting value is used to
initialize the object.
When initializing a scalar type, you may optionally enclose the
initializer in braces. However, they are normally elided. For example,
int i = {3};
is normally specified as
int i = 3;
When initializing the members of an aggregate, the initializer is a
brace-enclosed list of initializers. In the case of a structure with
automatic storage duration, the initializer may be a single expression
returning a type compatible with the structure. If the aggregate
contains members that are aggregates, this rule applies recursively, with
the following exceptions:
* Inner braces may be optionally elided.
* Members that are themselves aggregates cannot be initialized with
a single expression, even if the aggregate has automatic storage
duration.
In ANSI mode, the initializer lists are parsed "top-down;" in non-ANSI
mode, they are parsed "bottom-up." For example,
int q [3] [3] [2] = {
{ 1 },
{ 2, 3 },
{ 4, 5, 6 }
};
produces the following layout:
ANSI Mode Non-ANSI Mode
--------- ------------------
1 0 0 0 0 0 1 0 2 3 4 5
2 3 0 0 0 0 6 0 0 0 0 0
4 5 6 0 0 0 0 0 0 0 0 0
It is advisable to either fully specify the braces, or fully elide all
but the outermost braces, both for readability and ease of migration from
non-ANSI mode to ANSI mode.
Because the compiler counts the number of specified initializers, you do
not need to specify the size in array declarations. The compiler counts
the initializers and that becomes the size:
int x[ ] = {1, 10, 30, 2, 45};
This declaration allocates an array of int called x with a size of five.
The size is not specified in the square brackets; instead, the compiler
infers it by counting the initializers.
As a special case, you can initialize an array of characters with a
character string literal. If the dimension of the array of characters is
not provided, the compiler counts the number of characters in the string
literal to determine the size of the array. Note that the terminating
'\0' is also counted. For example:
char message[ ] = "hello";
This example defines an array of characters named message that contains
six characters. It is identical to the following:
char message[ ] = {'h','e','l','l','o','\0'};
You can also initialize a pointer to characters with a string literal:
char *cp = "hello";
This declares the object cp as a character pointer initialized to point
to the first character of the string "hello".
It is illegal to specify more initializers in a list than are required to
initialize the specified aggregate. The one exception to this rule is
the initialization of an array of characters with a string literal.
char t[3] = "cat";
This initializes the array t to contain the characters c, a, and t. The
trailing '\0' character is ignored.
If there are not enough initializers, the remainder of the aggregate is
initialized to zero.
More examples include:
char *errors[ ] = {
"undefined file",
"input error",
"invalid user"
};
In this example, the array errors is an array of pointers to character
(strings). The array is initialized with the starting addresses of three
strings, which will be interpreted as error messages.
An array with element type compatible with wchar_t (unsigned int) may be
initialized by a wide string literal, optionally enclosed in braces.
Successive characters of the wide string literal initialize the members
of the array. This includes the terminating zero-valued character, if
there is room or if the array is of unknown size.
Examples
wchar_t wide_message[ ]=L"x$$z";
You initialize structures as you do any other aggregate:
struct{
int i;
unsigned u:3;
unsigned v:5;
float f;
char *p;
} s[ ] = {
{1, 07, 03, 3.5, "cats eat bats" },
{2, 2, 4, 5.0, "she said with a smile"}
};
Note that the object being declared (s) is an array of structures without
a specified dimension. The compiler counts the initializers to determine
the array's dimension. In this case, the presence of two initializers
implies that the dimension of s is two. You can initialize named
bit-fields as you would any other member of the structure.
If the value used to initialize a bit-field is too large, it is truncated
to fit in the bit-field.
For example, if the value 11 were used to initialize the 3-bit field u
above, the actual value of u would be 3 (the top bit is discarded).
A struct or union with automatic storage duration can also be intialized
with a single expression of the correct type.
Example
struct SS { int y; };
extern struct SS g(void);
func()
{
struct SS z = g();
}
When initializing a union, since only one union member can be active at
one time, the first member of the union is taken to be the initialized
member.
Union initialization is only available in ANSI mode.
Example
union {
int i;
float f;
unsigned u:5;
} = { 15 };
MPE/iX 5.0 Documentation