public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c/69960] "initializer element is not constant"
       [not found] <bug-69960-4@http.gcc.gnu.org/bugzilla/>
@ 2021-09-27 20:42 ` pinskia at gcc dot gnu.org
  2023-02-22 10:14 ` daniel.lundin.mail at gmail dot com
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 8+ messages in thread
From: pinskia at gcc dot gnu.org @ 2021-09-27 20:42 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69960

Andrew Pinski <pinskia at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
   Target Milestone|---                         |8.0

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [Bug c/69960] "initializer element is not constant"
       [not found] <bug-69960-4@http.gcc.gnu.org/bugzilla/>
  2021-09-27 20:42 ` [Bug c/69960] "initializer element is not constant" pinskia at gcc dot gnu.org
@ 2023-02-22 10:14 ` daniel.lundin.mail at gmail dot com
  2023-02-22 11:47 ` daniel.lundin.mail at gmail dot com
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 8+ messages in thread
From: daniel.lundin.mail at gmail dot com @ 2023-02-22 10:14 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69960

Daniel Lundin <daniel.lundin.mail at gmail dot com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |daniel.lundin.mail at gmail dot co
                   |                            |m

--- Comment #19 from Daniel Lundin <daniel.lundin.mail at gmail dot com> ---
This ought to be discussed again. "clang allows it" is not an argument. 

First of all, it is questionable if gcc is still conforming after the change
discussed here and implemented as per gcc 8.0. Yes "an implementation may
accept other forms of constant expressions" but that doesn't mean that a
compiler is allowed to ignore the constraints in C17 6.7.9/4 nor the definition
of an integer constant expression. So this ought to explicitly be a compiler
extension and we ought to have a way to reliably compile strictly conforming
programs with gcc without constraint violations silently getting ignored. 

So if this feature is desired as an extension (I'm sure it is), then the old
diagnostic message should still be there when compiling as -std=c17 -pedantic.
See detailed discussion and relevant ISO 9899 quotes here:
https://stackoverflow.com/questions/68252570/why-are-const-qualified-variables-accepted-as-initializers-on-gcc

On top of that mess, I just found out that gcc behaves inconsistently in
regards of constant expressions between compiler ports. All gcc ports reject an
initializer such as (uint32_t)&function_pointer as they ought, except gcc for
ARM32 which silently allows this even under strict mode. This as per
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108875 which I think is NOT a bug,
since the definition of an arithmetic constant expression (6.6) always had
"Cast operators in an arithmetic constant expression shall only convert
arithmetic types to arithmetic types". A function/object pointer is not an
arithmetic type. A normative "shall" was violated. A conforming compiler must
issue a diagnostic. 

If the C standard by design blocks meaningful use of some constant expressions
inside initializer lists (I would agree that it does, the linked bug report
above is a very valid use-case in embedded systems), then gcc has the option to
make an extension and only warn in -pedantic mode. Bug again, this route was
not taken there either. Standard compliance was just silently abandoned in the
ARM32 port.

Therefore the current state of affairs is: gcc <8.0 (IMO compliant) behaves
differently from gcc >=8.0 which in turn behaves differently from gcc ARM32 any
version. Three different gcc behaviors for a language feature which has NOT
changed at all between C90 to C17.

All of this has to be revisited for the C23 constexpr/"named constants" 
implementation, so it would be great if we at the same time can separate
non-standard extensions from -pedantic mode. Notably C23 does not allow casts
from non-arithemtic types inside arithmetic constant expressions either.

Also note that C23 changed the wording slightly from C17: "An implementation
may accept other forms of constant expressions; however, they are not an
integer constant expression." I don't know why but likely because of some
implemented DR.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [Bug c/69960] "initializer element is not constant"
       [not found] <bug-69960-4@http.gcc.gnu.org/bugzilla/>
  2021-09-27 20:42 ` [Bug c/69960] "initializer element is not constant" pinskia at gcc dot gnu.org
  2023-02-22 10:14 ` daniel.lundin.mail at gmail dot com
@ 2023-02-22 11:47 ` daniel.lundin.mail at gmail dot com
  2023-02-22 17:00 ` joseph at codesourcery dot com
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 8+ messages in thread
From: daniel.lundin.mail at gmail dot com @ 2023-02-22 11:47 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69960

--- Comment #20 from Daniel Lundin <daniel.lundin.mail at gmail dot com> ---
Further info about the "ARM32 port bug". 

In case you write code like `(uint32_t)&function_pointer` and the port happens
to use 32 bit pointers, the non-conforming cast is let through. 

In case you cast to an integer type of different size in relation to the
pointer size (non-portable cast), you first get a warning about that: "warning:
cast from pointer to integer of different size [-Wpointer-to-int-cast]",
followed by the diagnostic "error: initializer element is not computable at
load time".

https://godbolt.org/z/xjYvd41qe

Correct compiler behavior here is to always give a diagnostic for
(uint32_t)&reset_handler not being an acceptable arithmetic constant
expression. 

If that's the same "implementation may accept other forms of constant
expressions"  bug as originally discussed here or a different bug, I don't
know.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [Bug c/69960] "initializer element is not constant"
       [not found] <bug-69960-4@http.gcc.gnu.org/bugzilla/>
                   ` (2 preceding siblings ...)
  2023-02-22 11:47 ` daniel.lundin.mail at gmail dot com
@ 2023-02-22 17:00 ` joseph at codesourcery dot com
  2023-02-22 17:03 ` joseph at codesourcery dot com
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 8+ messages in thread
From: joseph at codesourcery dot com @ 2023-02-22 17:00 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69960

--- Comment #21 from joseph at codesourcery dot com <joseph at codesourcery dot com> ---
On Wed, 22 Feb 2023, daniel.lundin.mail at gmail dot com via Gcc-bugs wrote:

> First of all, it is questionable if gcc is still conforming after the change
> discussed here and implemented as per gcc 8.0. Yes "an implementation may
> accept other forms of constant expressions" but that doesn't mean that a
> compiler is allowed to ignore the constraints in C17 6.7.9/4 nor the definition
> of an integer constant expression. So this ought to explicitly be a compiler
> extension and we ought to have a way to reliably compile strictly conforming
> programs with gcc without constraint violations silently getting ignored. 

"integer constant expression" does not mean the same thing as "constant 
expression of integer type".  If you use this expression in a context 
requiring an integer constant expression (case label, bit-field width, 
array designator in initializer, enum value, array size at file scope, 
constexpr initializer for object of integer type, etc.), it's properly 
rejected as required; in contexts where both integer constant expressions 
and other expressions are valid but with different semantics (e.g. 
determining whether something is a null pointer constant, determining 
whether an array is a VLA in a context where both VLA and non-VLA arrays 
are valid), again it's treated as non-constant.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [Bug c/69960] "initializer element is not constant"
       [not found] <bug-69960-4@http.gcc.gnu.org/bugzilla/>
                   ` (3 preceding siblings ...)
  2023-02-22 17:00 ` joseph at codesourcery dot com
@ 2023-02-22 17:03 ` joseph at codesourcery dot com
  2023-02-23  7:43 ` daniel.lundin.mail at gmail dot com
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 8+ messages in thread
From: joseph at codesourcery dot com @ 2023-02-22 17:03 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69960

--- Comment #22 from joseph at codesourcery dot com <joseph at codesourcery dot com> ---
I do however expect there may be cases in GCC 13 where constexpr 
initializers of floating type are accepted that do not meet the definition 
of arithmetic constant expressions, since GCC is generally a lot more 
careful about ensuring things are integer constant expressions when 
required than it is about doing the same for arithmetic constant 
expressions (before C2x there weren't any cases that allowed arithmetic 
constant expressions without also allowing other kinds of constant 
expressions permitted in initializers).

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [Bug c/69960] "initializer element is not constant"
       [not found] <bug-69960-4@http.gcc.gnu.org/bugzilla/>
                   ` (4 preceding siblings ...)
  2023-02-22 17:03 ` joseph at codesourcery dot com
@ 2023-02-23  7:43 ` daniel.lundin.mail at gmail dot com
  2023-02-23 18:38 ` joseph at codesourcery dot com
  2023-02-24  7:52 ` daniel.lundin.mail at gmail dot com
  7 siblings, 0 replies; 8+ messages in thread
From: daniel.lundin.mail at gmail dot com @ 2023-02-23  7:43 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69960

--- Comment #23 from Daniel Lundin <daniel.lundin.mail at gmail dot com> ---
(In reply to joseph@codesourcery.com from comment #21)
> On Wed, 22 Feb 2023, daniel.lundin.mail at gmail dot com via Gcc-bugs wrote:
> 
> > First of all, it is questionable if gcc is still conforming after the change
> > discussed here and implemented as per gcc 8.0. Yes "an implementation may
> > accept other forms of constant expressions" but that doesn't mean that a
> > compiler is allowed to ignore the constraints in C17 6.7.9/4 nor the definition
> > of an integer constant expression. So this ought to explicitly be a compiler
> > extension and we ought to have a way to reliably compile strictly conforming
> > programs with gcc without constraint violations silently getting ignored. 
> 
> "integer constant expression" does not mean the same thing as "constant 
> expression of integer type".  

Yes, who said otherwise? Rather, this is the problem. Please check out the link
I gave for the full reasoning including quotes.
https://stackoverflow.com/questions/68252570/why-are-const-qualified-variables-accepted-as-initializers-on-gcc

Specifically (C17 6.6):

"An integer constant expression shall have integer type and shall only have
operands that are integer constants, enumeration constants, character
constants, sizeof expressions whose results are integer constants, _Alignof
expressions, and floating constants that are the immediate operands of casts."

In this code 

static const int y = 1;
static int x = y;

y is not an integer constant expression, nor is it an integer constant in the
meaning that ISO 9899 defines it. Therefore an initializer was given which is
not a constant expression. Therefore this is a constraint violation of C17
6.7.9/4 and a diagnostic must be issued. Therefore gcc is not conforming
because of the "bug fix" carried out above.

"an implementation may accept other forms of constant expressions" does not
mean that an implementation can throw out any constraints it pleases out the
window. Also the text "however, they are not an integer constant expression"
added in C23 must have been added for a reason, such as misbehaving compilers.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [Bug c/69960] "initializer element is not constant"
       [not found] <bug-69960-4@http.gcc.gnu.org/bugzilla/>
                   ` (5 preceding siblings ...)
  2023-02-23  7:43 ` daniel.lundin.mail at gmail dot com
@ 2023-02-23 18:38 ` joseph at codesourcery dot com
  2023-02-24  7:52 ` daniel.lundin.mail at gmail dot com
  7 siblings, 0 replies; 8+ messages in thread
From: joseph at codesourcery dot com @ 2023-02-23 18:38 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69960

--- Comment #24 from joseph at codesourcery dot com <joseph at codesourcery dot com> ---
On Thu, 23 Feb 2023, daniel.lundin.mail at gmail dot com via Gcc-bugs wrote:

> In this code 
> 
> static const int y = 1;
> static int x = y;
> 
> y is not an integer constant expression, nor is it an integer constant in the
> meaning that ISO 9899 defines it.

Correct, but irrelevant, since nothing in that code example is required by 
the standard to be an integer constant expression.

> Therefore an initializer was given which is
> not a constant expression.

No, it's an "other form of constant expression" accepted by GCC.

> "an implementation may accept other forms of constant expressions" does not
> mean that an implementation can throw out any constraints it pleases out the
> window.

Correct.  The Constraints on constant expressions say "Constant 
expressions shall not contain assignment, increment, decrement, 
function-call, or comma operators, except when they are contained within a 
subexpression that is not evaluated." and "Each constant expression shall 
evaluate to a constant that is in the range of representable values for 
its type.".  The initializer is entirely consistent with those 
Constraints, so it is within the bounds of what an implementation may 
accept as an "other form of constant expression".  Whereas it wouldn't be 
valid for an implementation to accept f() as a constant expression 
(contains a function call), for example.

Note also that only violations of Syntax and Constraints require 
diagnostics (and thus -pedantic doesn't claim to ensure diagnostics for 
code that's not strictly conforming for some other reason than violating 
Syntax or Constraints).

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [Bug c/69960] "initializer element is not constant"
       [not found] <bug-69960-4@http.gcc.gnu.org/bugzilla/>
                   ` (6 preceding siblings ...)
  2023-02-23 18:38 ` joseph at codesourcery dot com
@ 2023-02-24  7:52 ` daniel.lundin.mail at gmail dot com
  7 siblings, 0 replies; 8+ messages in thread
From: daniel.lundin.mail at gmail dot com @ 2023-02-24  7:52 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69960

--- Comment #25 from Daniel Lundin <daniel.lundin.mail at gmail dot com> ---
(In reply to joseph@codesourcery.com from comment #24)
> On Thu, 23 Feb 2023, daniel.lundin.mail at gmail dot com via Gcc-bugs wrote:
> 

Regardless of how one chose to read that part of the standard, fact remains
that this part of the standard has not changed since C89 but still gcc behaves
wildly different depending on version. This makes it impossible to port
strictly conforming programs between different gcc versions, because then
you'll either get a diagnostic that you (arguably) shouldn't be getting, or you
will not get a diagnostic where you (arguably) should be expecting one. 

This makes gcc a hazard in my case. My choices are to forbid newer versions or
to port to a different compiler. In case -pedantic would still result in a
diagnostic past version 8 then that would make gcc behave consistently across
versions and that would solve the problem. As was already mentioned previously
in this thread, before this change was implemented with that remark ignored.

Additionally there is bug #2 where (uint32_t)&function_pointer does not give a
diagnostic in case the pointer is 32 bit, which is non-conforming behavior for
constant expressions. I should perhaps open a separate bug report about that
since I'm not sure if it's related to this one.

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2023-02-24  7:52 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <bug-69960-4@http.gcc.gnu.org/bugzilla/>
2021-09-27 20:42 ` [Bug c/69960] "initializer element is not constant" pinskia at gcc dot gnu.org
2023-02-22 10:14 ` daniel.lundin.mail at gmail dot com
2023-02-22 11:47 ` daniel.lundin.mail at gmail dot com
2023-02-22 17:00 ` joseph at codesourcery dot com
2023-02-22 17:03 ` joseph at codesourcery dot com
2023-02-23  7:43 ` daniel.lundin.mail at gmail dot com
2023-02-23 18:38 ` joseph at codesourcery dot com
2023-02-24  7:52 ` daniel.lundin.mail at gmail dot com

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).