This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: C constant expressions proposals
"Joseph S. Myers" <jsm@polyomino.org.uk> writes:
| On Sat, 14 Aug 2004, Gabriel Dos Reis wrote:
|
| > I would like to mention the following proposal
| >
| > Generalized Constant Expressions
| > http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2003/n1521.pdf
| >
| > that has been well received and encouraged at the Kona meeting of the
| > C++ standards meeting. I believe, in all modesty, that it is a
| > extension worth having in GNU C and GNU C++, pending final vote from
| > the C++ standards committee.
|
| This looks more in the spirit of C++ than C (since, for example, C does
| not include const variables in constant expressions).
It is true that C does not include const variables in constant
expressions, but I believe it should accept const variables with
either internal linkage or no linkage, initialized with integral
constant expressions, to be used in constant expressions.
| There is however no
| intrinsic problem with having such an extension to C when an appropriate
| attribute is used on the function definition (without, it would violate
| the constraint that constant expressions shall not contain function calls,
| and my proposals are designed to be safely within what ISO C permits
| without needing any reference to -pedantic - and implementation would
| incidentally get rid of one place where -pedantic might affect code
| generation).
I see, thanks for that clarification.
| I take it you require the body of such an inline function to be visible
| before the use of a call in a constant expression?
Yes, of course.
| Without that, at least
| in C you'd get nasty problems with making sense of the program at all.
Completely agreed. One gets the same nastiness in C++ too. I
absolutely have no intention to require compilers to solve the halting
problem. I formulated the rules pretty much in the spirit of what
CFront did to inline functions a very long time ago: use of an inline
function before it is defined is a hard error. That requirement is
what I formulated as:
[...] Such an expression may involve calls to previously defined
constant-valued functions with argument list consisting only in
constant expressions.
I'll add more explicit notes to clarify that point.
| Do you require the arguments to such a function to be integral constant
| expressions, and the function to return an integral type, for it to be
| used in integral constant expressions?
For integral constant expressions, yes.
| May parameters have floating point type?
Yes. As logn as the actual arguments are constant expressions, it is OK.
| What about floating point
| constants passed as arguments for
| parameters of integer type (and so implicitly converted to integer type,
| where an explicit conversion would be OK)?
Standard C++ tolerates floating point constants, immediately subject
to cast to integral types, in constant expressions. Function
arguments passing has the semantics of (copy-)initalization. So the
issue is reduced to know whether N, as declared below, is an integral
constant expression
const int N = 3.14;
The answer is yes. However, the following M is not an integral constant
expression
const int M = 1.0 * 3.14;
| I have found and corrected two bugs in the rules for GNU C constant
| expressions: they allowed such expressions as 1 - (intptr_t)&x, and didn't
| describe how typeof was handled. I have also adjusted them to allow unary
| plus on address constants of integer type, so that +(intptr_t)&x is just
| as valid as (intptr_t)&x.
Those makes sense to me.
| http://www.srcf.ucam.org/~jsm28/gcc/#const
|
| The models for C90 and C99 constant expressions remain unchanged.
For the GNU C part, shouldn't we be more precise about:
g) Built-in functions starting __builtin_ may be used in certain
circumstances in constant expressions: if the compiler can fold
them to an integer constant, floating constant or address
constant then they are treated as an integer constant
expression, arithmetic constant expression or address constant,
respectively. The exact circumstances in which they are folded
are unspecified, may depend on optimisation levels and are
subject to change.
I would prefer we don't make the "constantness" depend on optimization
level. The reason is that we should not make a program valid
depending on the optimization level -- users should be able to switch
from "-g -O2" to "-g -O0" or vice versa.
| Further comments on any aspects welcome. Given the past heated debates on
| the validity of gcc.c-torture/compile/20010327-1.c I'm a bit surprised at
| the lack of any comments on its reinvalidation (or more generally on the
| choice of extensions for GNU C; given past strongly stated opinions on
| such extensions both to constant expressions and elsewhere I'd have
| expected some people to object that there were too many useless extensions
| included and others (or indeed the same people) that important extensions
| used by real code were omitted).
:-) :-)
-- Gaby