| |||||||||||||
On-Line Manuals RealView Compiler User's Guide | Language features
The C99 standard introduces several new language features of interest to programmers, including:
A selection of new language features of C99 that might be of particular interest are discussed in the following sections. You can use ISO C99 supports compound literals. A compound literal looks like a cast followed by an initializer. Its value is an object of the type specified in the cast, containing the elements specified in the initializer. It is an lvalue. For example:
int y[] = (int []) {1, 2, 3};
int z[] = (int [3]) {1};
In C90, there is no way to initialize specific members of arrays, structures, or unions. C99 supports the initialization of specific members of an array, structure, or union by either name or subscript through the use of designated initializers. For example:
typedef struct
{
char *name;
int rank;
} data;
data vars[10] = { [0].name = "foo", [0].rank = 1,
[1].name = "bar", [1].rank = 2,
[2].name = "baz",
[3].name = "gazonk" };
Members of an aggregate that are not explicitly initialized are initialized to zero by default. C99 supports floating‑point numbers that can be written in hexadecimal format. For example:
float hex_floats(void)
{
return 0x1.fp3; // 1 15/16 * 2^3
}
In hexadecimal format the exponent is a decimal number that indicates the power of two by which the significant part is multiplied. Therefore In a struct with more than one member, the last member of the struct can have incomplete array type. Such a member is called a flexible array member of the struct. NoteWhen a struct has a flexible array member, the entire struct itself has incomplete type. Flexible array members enable you to mimic dynamic type specification in C in the sense that you can defer the specification of the array size to runtime. For example:
extern const int n;
typedef struct
{
int len;
char p[];
} str;
void foo(void){
size_t str_size = sizeof(str); // equivalent to offsetoff(str, p)
str *s = malloc(str_size + (sizeof(char) * n));
}
The object
extern const int n;
struct
{
int len;
char p[n];
} s;
The
void foo(void)
{
printf("This function is called '%s'.\n", __func__);
}
prints: This function is called 'foo'. The C99 keyword inline hints to the compiler that invocations of a function qualified with inline are to be expanded inline. For example:
inline int max(int a, int b)
{
return (a > b) ? a : b;
}
The compiler inlines a function qualified with inline only if it is reasonable to do so. It is free to ignore the hint if inlining the function adversely affects performance. See Inlining for more information. NoteThe semantics of inline in C99 are different to the semantics of inline in Standard C++. C99 supports the integral data type long long. This type is exactly 64 bits wide in RVCT. For example: long long int j = 25902068371200; // length of light day, meters unsigned long long int i = 94607304725808000ULL; // length of light year, meters See long long in the Compiler Reference Guide for more information. You can declare a macro in C99 that accepts a variable number of arguments. The syntax for defining such a macro is similar to that of a function. For example:
#define debug(format, ...) fprintf (stderr, format, __VA_ARGS__)
void Variadic_Macros_0()
{
debug ("a test string is printed out along with %x %x %x\n", 12, 14, 20);
}
C99 enables you to mix declarations and code within compound statements, just as in C++. For example:
void foo(float i)
{
i = (i > 0) ? -i : i;
float j = sqrt(i); // illegal in C90
}
In a for loop, the first expression may be a declaration, just as in C++. The scope of the declaration extends to the body of the loop only. For example:
extern int max;
for (int n = max - 1; n >= 0; n--)
{
// body of loop
}
is equivalent to:
extern int max;
{
int n = max - 1;
for (; n >= 0; n--)
{
// body of loop }
}
NoteUnlike in C++, you cannot introduce new declarations in a for-test, if-test or switch-expression. C90 does not permit a # define RWDATA(X) PRAGMA(arm section rwdata=#X) # define PRAGMA(X) _Pragma(#X) RWDATA(foo) // same as #pragma arm section rwdata="foo" int y = 1; // y is placed in section "foo" The C99 keyword restrict enables you to ensure that different object pointer types and function parameter arrays do not point to overlapping regions of memory. This enables the compiler to perform optimizations that might otherwise be prevented because of possible aliasing. In the following example, pointer
void copy_array(int n, int *restrict a, int *restrict b)
{
while (n‑‑ > 0)
*a++ = *b++;
}
void test(void)
{
extern int array[100];
copy_array(50, array + 50, array); // valid
copy_array(50, array + 1, array); // undefined behavior
}
Pointers qualified with restrict can however point to different arrays, or to different regions within an array. | ||||||||||||
| |||||||||||||