E. C99—A Brief Introduction – C Programming Essentials

Appendix E. C99—A Brief Introduction

C99 Outlines

Like all major softwares, programming languages are also updated from time to time. Since its creation in 1972, the C programming language has undergone several modifications. Most recent of these is the C99 standard published in the year 1999 in a document titled ‘ISO/IEC 9899:1999’. This appendix deals with the major changes that have happened from C89 to C99. Here, we present some of these features with brief examples.

Some Features Removed In C99

  • C99 drops the “implicit int” rule. In C89, absence of a type specifier resulted in the compiler assuming the default type to be int. This is especially true for return type of functions.

  • C99 also drops the “implicit function declaration” rule present in C89, by which an undeclared function could be used. A default declaration was assumed to be there.

New Additions In C99

Keywords

C99 reserves five new keywords:

  • _Bool

  • _Complex

  • _Imaginary

  • restrict

  • inline

The first three of them are new data types added to the languages to represent boolean, complex, and imaginary values, respectively. The names have been preceded with an underscore sign to distinguish them from many commercial libraries supporting types with similar names.

Features

Many new features have been incorporated in C99, the most significant of these being:

  • Support for arithmetic of complex numbers

  • Data type “long long int” has been added to represent 64-bit signed integer

  • New C++-like comment style using “//”

  • Variables can now be declared within for loop

  • Support for variable length arrays

  • New variables can now be declared within code (as in C++)

  • Minor changes in preprocessor

  • Ability to define compound literals

  • Ability to define a flexible sized array as the last member of a structure

  • Support for new designators

  • New predefined identifier __func__

  • New libraries added

Updation to C99 Standard

C99 standard has updated some of the C89 rules:

  • Translation limits have been increased (for example, capability to have >31 arguments in a function call, increase in number of significant characters in identifier names)

  • The integer type “int” has been extended with new types like “intmax_t”

  • Blank return statements disallowed

New Keywords

Inline

The keyword inline is applicable to functions. When applied to a function, the compiler is instructed to make calls to the function as fast as possible. In most of the cases, this means that the code of the function will be expanded in place of the call, like a macro. But it is just a request to the compiler, not a way to force inline expansion. C99, however, guarantees that the function call will be made as fast as possible.

Typical usage of inline is for small functions where the function call overhead is significant. It will also benefit those function calls that happen deep inside nested loops. The syntax for inline is:

inline void swap (int &a, int &b)
{
        int temp = *a;
        *a = *b;
        *b = temp;
}

Restrict

This is a new type qualifier for pointers introduced in C99. A restrict pointer is the only way to access the object(s) pointed to by the pointer. If we want to access it through another pointer, it must be based on the original pointer. Restrict pointers find their use as function parameters to ensure that they are the only means of accessing the memory. A typical example is the library function memcpy(), whose result is undefined if the objects pointed to by its two pointer arguments overlap. If we use the following prototype for memcpy(), we can ensure that the objects are non-overlapping.

void *memcpy (void *restrict p1, void *restrict p2, size_t size);

New Types

Bool

Unlike other languages, C never had a boolean type. This data type was added by C99 to address this shortcoming. The name was “_Bool” and not “bool”, so that old programs that had created their own type “bool” would compile properly. The header file “stdbool.h” defines the macros “bool” (the data type) as well as “true” and “false”. This header is to be used for developing new programs.

Complex and _Imaginary

These types added the much-demanded support to C for complex arithmetic. Here also, the naming style follows the same rule as in “_Bool”. The header file “complex.h” defines the macros “complex” and “imaginary” (data types). C99 defines the following complex types:

  • float _Complex

  • float _Imaginary

  • double _Complex

  • double _Imaginary

  • long double _Complex

  • long double _Imaginary

Long Long Int

The new type “long long int” and its unsigned variation added by C99 enable developers to use a new 64-bit integer type in their programs.

New Features In C99

Single-line Comments

C99 adds support to C++ like comments. Anything appearing after “//” and before a line break is considered to be a comment.

void print ( int ) // function to print an integer

Variable Declaration Within for Loop

Variables can now be declared within a for loop:

for (int i=0; i<10; ++i)
    printf("%d",i);

The scope for the variable is till the end of the loop. In the above example, the variable i declared within the ‘for’ loop cannot be used after the for loop ends.

Variable-sized Arrays

C99 adds this interesting feature to C by which local arrays can have variable length. Any integer (even those that are determined at runtime) can specify the size of the array. For example, in the merge function of merge-sort, the auxiliary array could be defined like:

void merge (int arr[], int lo, int mid, int hi)
{
     int aux[hi-lo+1]; // variable sized array

Introduction of variable length arrays brings about a change in the sizeof() operator. In C89, sizeof() is a compile time operator, but for variable-length arrays it is determined at runtime.

Declaration of Variable Within Code

Like C++, C99 now supports declaration of variables within code segments, unlike declaring them at the beginning of the block as in C89. So, we can write code of the form:

void myfunc()
{
    int x=10;
    printf("x=%d",x);
    int y=20;
    printf("and y=%d",y);
}

This helps in writing easier-to-understand programs as the variables can be declared closer to their place of use.

Compound Literals

A compound literal looks like a cast containing an initializing value of constants of almost any type including struct, union, and array. For example, we can now write:

struct point { int a, b; };
struct point p1 = (struct point) {0,2};
struct point p2 = (struct point) {4,1};
int *arr = (int[]) {1, 2, 3};
// arr now points to an integer array of 3 elements

Moreover, such compound literals can be used anywhere in place of an object with the same type of the compound literal. Like:

int var;
var = (int){1} + (int){2};     // var=3 now

Flexible-sized Arrays

In C99, we can declare an unsized array as the last member of a structure. This allows the structure to contain an array of variable size. But sizeof() applied to the structure would not return the size of the array. To allocate an object of this type of structure, the syntax should be:

struct myStruct {
    int var;
    int arr[];
}
struct myStruct *p;
p = (struct myStruct *) malloc( sizeof(struct
                        myStruct)+5*sizeof(int) );

Now, p is a pointer to a struct to type “struct myStruct” with length of array equal to five.

Designated Initializer

C99 adds support for a new type of initializers, suitable when one needs to initialize only a few members of an array or a structure. The following is the syntax for arrays:

int arr[100] = { [1]=1, [11]=2, [38]=3, [97]=4 };
// this initializes only arr[1], arr[11], arr[38] and arr[97]

Example for structures:

struct myStruct {
    int a;
    int b;
    int c;
}
struct myStruct var = { .b=10 };
// only the variable var.b was assigned a value 10

Here, we have presented a very brief introduction to C99. This might be useful to interested readers, who may explore the language features and use it effectively.