GCC Extensions
I have been using GCC quite much, but I haven’t really ever used its extensions (except some C99 features in C90). Recently, I stumbled upon the documentation of all the extensions, so I figured to list few of the special ones here.
Function overloading
By using __typeof__
and __builtin_types_compatible_p(type1, type2)
, it is
possible to (kinda) overload functions in C. Let’s say for example that you want
to implement is_equal
function, which would work on integers and strings. By
using __builtin_types_compatible_p
you could check what type the given
parameter is, and then call the appropriate function.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
|
Cleanup when variable goes out of scope
With GCC’s variable attributes, you can specify a function that is to be called when the variable goes out of scope. This function receives a pointer to the parameter, so it can be used e.g. to close a file:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
|
Built-in apply
1 2 |
|
As you may (or may not) know, the function declarations above mean quite different things in C. The first one accepts any number of arguments (of any type) and the second one doesn’t accept any arguments at all. Hence, first one could be called as (and compilers should consider it valid):
1
|
|
but you cannot really access the variable since you don’t give it any name (or
even type) in the definition. But here comes __builtin_apply
and
__builtin_apply_args
to the picture. With __builtin_apply_args
you get a
pointer to arguments given to the function and with __builtin_apply(void
(*function)(), void *arguments, size_t size)
, you can call a different function
with the arguments. So, for example:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
|
And it prints:
1 2 3 |
|
Extended ASM
You can easily embed assembly instructions to .c file and even read and write C variables from assembler (this is quite heavily used in Linux kernel). For example, if you would like to read the number of CPU cycles since reset, you could write (on x86):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
|
Nested Functions
Using GCC, you can actually have functions inside functions.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
|
Here, inside func
, another function (func2
) is first declared and then
defined. Forward-declaration is not necessary here, but in order to do so, you
actually must use auto
(this is probably the only place where auto
is
needed). func
returns a pointer to the nested function so it can also be used
outside of the function (with some restrictions).
Case ranges
You can have a range in a switch-case:
1 2 3 4 5 6 7 8 9 10 11 |
|
Forward-declaration of enum
It is possible to declare an enumeration without specifying its values. There is not much that can be done with it, but it seems that it was added so enums would be handled similarly as structs or unions. Before this, I didn’t even know it is forbidden in ISO C.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
|
Complete sources of these examples (and few more) can be found in github. Rest of the extensions (and more through documentation of them) can be found from GCC docs.