This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: C constant expressions proposals


On Sat, 14 Aug 2004, Gabriel Dos Reis wrote:

> | 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.

I believe in this matter we should wait to be led by WG14 if they want to 
expand the notion of constant expressions in C, as hitherto WG14 has not 
chosen (with the example of C++ to hand, and they certainly considered 
what C++ features might appropriately be added to C) rather than adding 
const variables (which C treats as accessing the value of a (constant) 
object rather than as being constants, and in C const does not affect 
linkage) to the valid parts of constant expressions.  This question isn't 
fundamental to the spirit of C; WG14 could choose to change it in future; 
but bearing in mind that such extensions don't have much benefit (C 
programmers are used to using #define for constants, for all its faults) 
and would tend to lead to people writing code with GCC that fails to be 
portable to other compilers, I just think we don't need such an extension.  
(Without regard to the question of whether such an extension is within the 
implementation latitude to add other forms of constant expression.)

In various cases when arithmetic is done on const variables we do 
accidentally accept them in constant expressions, depending on 
optimization and other random factors; this is bug 5675, plus a regression 
since 24 March (for which I haven't filed a separate bug or upgraded that 
one, given that sort of regression clearly isn't going to block a 
release).  One point of giving (and implementing) precise models is to 
stop such random variation; it just so happens the C-like way of stopping 
it means consistently treating const variables like non-const ones.

Since C has tentative definitions, you'd need the initializer to be 
visible before the use in the constant expression.  You should also 
exclude volatile const variables.

> 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

That certainly simplifies the use of inline functions!  C99 says that a 
call to an inline function can use either the definition in that 
translation unit (which may be before or after the call), or the 
non-inline definition in another translation unit, but not an inline 
definition from another translation unit.  All these definitions may be 
distinct; C99 deliberately (discussed in the Rationale) did not adopt the 
ODR.

> 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.

The situation is that a precise specification is difficult - some 
functions may not result in a constant with constant arguments, while 
non-integer arguments may quite legitimately result in integer constants 
in some cases.  I also suspect real code is using such cases, beyond those 
documented, in constant expressions in initializers.  Thus I discourage 
use in constant expressions, while expressly noting those cases such as 
__builtin_nan for which we have made guarantees that they can be used as 
such in standard headers.  Effectively this leaves a "window onto the 
implementation", albeit much smaller than at present, where we have never 
specified constancy but some users may reasonably be using it.  To make 
things more precise we'd either say "never constant, except for this short 
list of functions" (and take the user complaints), or else keep updating a 
list of precisely which mathematical functions (for example) we fold, and 
when (and we fold some only for particular arguments).  When folding 
arithmetic constant expressions, FENV_ACCESS complicates matters as well 
(i.e. except in static initializers we can't fold, but VLA constraints 
expect us to, and there was a view in the UK C Panel that the problem 
there might be that the expression was still considered constant in the 
presence of FENV_ACCESS rather than in the VLA constraints).  As the 
standard is of course silent on __builtin_ function calls, there's no 
great value in arbitrarily annoying users by restricting them.

VLAs in structures form another underspecified case, although there 
because I think deprecating them is the right solution; I think their 
semantics are full of holes that we don't want to try to fill, and they 
don't work reliably as shown by many bug reports past and present.

-- 
Joseph S. Myers               http://www.srcf.ucam.org/~jsm28/gcc/
    jsm@polyomino.org.uk (personal mail)
    jsm28@gcc.gnu.org (Bugzilla assignments and CCs)


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]