9. Configuration for expressions
9.1. Cast expressions
ISO C++ introduces the constructs static_cast
, const_cast
and reinterpret_cast
, which can be used in various contexts where an old style explicit cast would previously have been used. By default, an explicit cast can perform any combination of the conversions performed by these three constructs. To aid migration to the new style casts the directives:
#pragma TenDRA++ explicit cast as cast-state allow #pragma TenDRA++ explicit cast allow
where cast-state is defined as follows:
cast-state : static_cast const_cast reinterpret_cast static_cast | cast-state const_cast | cast-state reinterpret_cast | cast-state
can be used to restrict the conversions which can be performed using explicit casts. The first form sets the interpretation of explicit cast to be combinations of the given constructs; the second resets the interpretation to the default. For example:
#pragma TenDRA++ explicit cast as static_cast | const_cast allow
means that conversions requiring reinterpret_cast
(the most unportable conversions) will not be allowed to be performed using explicit casts, but will have to be given as a reinterpret_cast
construct. Changing allow
to warning
will also cause a warning to be issued for every explicit cast expression.
9.2. Initialiser expressions
C, but not C++, only allows constant expressions in static initialisers. The directive:
#pragma TenDRA variable initialization allow
can be enable support for C++-style dynamic initialisers. Conversely, it can be used in C++ to detect such dynamic initialisers.
In older dialects of C it was not possible to initialise an automatic variable of structure or union type. This can be checked for using the directive:
#pragma TenDRA initialization of struct/union (auto) allow
The directive:
#pragma TenDRA++ complete initialization analysis on
can be used to check aggregate initialisers. The initialiser should be fully bracketed (i.e. with no elision of braces), and should have an entry for each member of the structure or array.
9.3. Lvalue expressions
C++ defines the results of several operations to be lvalues, whereas they are rvalues in C. The directive:
#pragma TenDRA conditional lvalue allow
is used to apply the C++ rules for lvalues in conditional (?:
) expressions.
Older dialects of C++ allowed this
to be treated as an lvalue. It is possible to enable support for this dialect feature using the directive:
#pragma TenDRA++ this lvalue allow
however it is recommended that programs using this feature should be modified.
The ?
operator cannot normally be used to define an lvalue, so that for example, the program:
struct s { int a, b; }; void f ( int n, struct s *s1, struct s *s2 ) { ( n ? s1 : s2) -> a = 0; }
is not allowed in ISO C. The pragma:
#pragma TenDRA conditional lvalue allow
allows conditional lvalues if:
-
Both options of the conditional operator have compatible compound types;
-
Both options of the conditional are lvalues.
(there is also a disallow
variant, but warning
is not permitted in this case).