Are some builtin functions (for example log() vs. sqrt()) more equal than others?

Joseph Myers joseph@codesourcery.com
Fri Jul 30 20:51:21 GMT 2021


On Fri, 30 Jul 2021, Stefan Kanthak wrote:

> Joseph Myers <joseph@codesourcery.com> wrote:
> 
> > None of these are valid constant expressions as defined by the standard 
> > (constant expressions cannot involve evaluated function calls).
> 
> That's why I ask specifically why GCC bugs on log(log(...)), but not on
> log(sqrt(...) ...)!

The log(log(1.0)) example you gave would raise divide-by-zero.

> > Some might be accepted as an extension, but I expect that since the 
> > optimization for constant arguments is intended for valid calls that
> > would otherwise be executed at runtime, not for static initializers,
> > it's avoiding optimizations that would result in the loss of floating-
> > point exception flag raising.
> 
> That's no valid excuse: by the standard, the compiler is free to execute
> static initializers during runtime, before calling the main() routine.

The point of this extension isn't to accept as much as possible.  Rather, 
it turned out when I implemented standard constant expression rules for 
GCC 4.5 that lots of existing code was using just about anything GCC could 
fold into a constant in just about any context requiring a constant 
expression.  So for compatibility with existing, questionable, pre-GCC-4.5 
code, we still allow "expressions that can be folded into a constant" in 
various such contexts, with a pedwarn-if-pedantic.  But because this isn't 
a designed, documented extension or something it's actually considered 
good practice to use, the semantics remain "expressions that can be folded 
into a constant", with all the dependence that implies on the folding GCC 
does for optimization purposes - and that folding is designed for 
optimizing code outside of static initializers, not for use in this 
extension, with all the corresponding implications for its design.

So if some expression doesn't get folded to a constant outside of static 
initializers (or for that matter, if it does get so folded, but previous 
GCC versions didn't accept it in static initializers, since this extension 
is about compatibility with existing code), it's not a bug for it not to 
be accepted in a static initializer.

If, outside of static initializers, some of these expressions don't get 
folded to a constant *even with -fno-trapping-math*, that's a missed 
optimization and it would make sense to improve the compiler to fold them 
given -fno-trapping-math.

Executing static initializers at runtime seems more like a C++ thing; it's 
not within the conventional concept of how C maps to object files.

-- 
Joseph S. Myers
joseph@codesourcery.com


More information about the Gcc mailing list