The GNU C++ compiler has many extensions to the standard. The most widespread version, 2.95, is mature, stable, but very much outdated with regard to the C++ standard. The new 3.x version hews much closer to the standard, while retaining the familiar GNU extensions. This section presents highlights of only a few of the extensions.
_ _attribute_ _
A function can be modified with attributes to tell the
compiler about the function. For example, _ _attribute_ _((noreturn))
tells the
compiler that the function does not return, which enables the
compiler to remove unneeded code, such as statements that follow
calls to the function. Some attributes can apply to objects,
labels, and types. Several different attributes are supported,
such as:
always_inline
Always expand this function inline, even if optimizations are disabled.
const
The function has no side effects and does not depend on any global variables; therefore, the compiler can replace repeated calls to the function with a single call, saving the result.
deprecated
The function, object, or type is deprecated. Using a
deprecated
entity results
in a compiler warning.
dllexport
On Windows, marks the function as exported from a DLL.
pure
Slightly less strong than const
, a pure function has no side
effects but can depend on global variables. The compiler can
optimize away repeated calls when it knows intervening code
does not modify any global variables.
case
range
In a switch
statement, a
single case
label can specify a range of values:
switch(c) { case 'a' . . . 'z': case 'A' . . . 'Z': do_english_letter(c); break; // . . . Other cases, etc. }
long
long
The long
long
type is an
integral type that has at least 64 bits. A long
long
literal is written with a suffix of
LL
(e.g., 10000000000000LL
).
The operators <?
and
>?
return the minimum and
maximum of their two operands. You can overload these operators
the way you would any other operator:
template<typename T> T max3(const T& a, const T& b, const T& c) { return a >? b >? c; }
typeof
The typeof
keyword takes an expression as an operand and
yields the type of the expression. You can use typeof
wherever you can use a type
identifier. Templates create a need for typeof
because when writing the
template, you have no way of knowing the return type of an
operator or function. For example:
template<typename T, typename U> typeof(T+U) incr(const T& t, const U& u) { return t + u; }