Introduction
C99 is the 1999 standard of the C programming language. C is a simple, low level language, that is best suited for systems programming.This article will present a number of C99's features. Some of these features have yet to appear in C++, and therefore might not be familiar to some C++ programmers.
We will start off easy, with minor backports from C++, then move up to C99-only features, to wrap it up with "serious" code, adapted for this article from a small, real life project.
The source code in this article was tested to compile with Pelles C IDE 7, however due to the popularity and age of C99, the code should build fine with many other C compilers. Just be sure to enable C99 support, if needed.
No mandatory return for main()
As in C++, if the return statement is omitted in the main()
function, a return 0;
is
implied.Booleans
The_Bool
data type is introduced, which behaves like an unsigned integer capable of storing only 1 or 0.The supporting header stdbool.h contains the macros
bool
, true
and false
expanding
to _Bool
, 1 and 0 respectively.Example:
|
|
Output:
0 1 0 1 |
%zu
for size_t
The %zu
format specifier was introduced specifically for size_t
,
so as to clear the confusion of having to choose in between the unsigned integer specifiers %u
, %lu
,
and more recently %llu
.Example:
|
|
Possible output:
4294967295 |
Functions know their own name
The__func__
identifier behaves like a constant char
array
containing the name of the function where it is invisibly declared.Example:
|
|
Output:
i_know_my_name main |
Variable-length arrays
The variable-length arrays (or VLA's) are arrays that can be declared by using a variable, instead of a compile-time constant, for their size. They do not have variable length as in being able to resize.VLA's are infamous because they're allocated on the stack and not the heap. The stack area is used for local variables, and is more limited in size than the heap. If the size of the VLA is too big, a stack overflow will occur, resulting in a crash.
Still, the VLA is a very useful tool when the programmer wants to use small arrays, while avoiding the tedious
malloc()
+ free()
business.Example:
|
|
Sample output:
Please input `n': 10 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 |
Variadic macros
Functions can accept a variable number of parameters by using the ellipsis (...
). Starting from C99, so too can macros.
In the macro's definition, __VA_ARGS__
will be used to expand the parameters.Example:
|
|
Sample output:
Wed Apr 3 12:33:23 2013 -> Hello User, your number is 75! Please wait... Wed Apr 3 12:33:33 2013 -> So how's it going? |
Designated initializers
C99 offers a way to control which member in a structure, or which element in an array, to initialize and to what value.It's easier to just jump into the example for this one.
Example:
|
|
Output:
Contents of ca: a b c d e 0 0 0 0 z Contents of t: c == Z i == 10 f == 3.140000 |
Compound literals
A compound literal is basically a nameless variables, and looks very similar to a cast. It works together beautifully with variadic macros and designated initializers to produce clean, high-level looking code.In the simplest usage scenario, compound literals take the place of temporary variables, which we don't care to have around.
Example:
|
|
Output:
flip_case() Before: Hello C99 World! After: hELLO c99 wORLD! add_ten() Before: 5 After: 15 kill_evens() Before: 2 3 29 90 5 6 8 0 After: 3 3 29 91 5 7 9 1 Current time: Wed Apr 3 12:44:55 2013 |
For a more advanced example demonstrating the value of compound literals, consider this scenario: we've written our own
strscat()
function,
which is basically a strcat()
with an extra parameter for maximum length, and we want to test to see if it works correctly.Now, I'll let the code talk.
|
|