On 10/11/2022 20:16, Florian Weimer via Gcc wrote:
* Marek Polacek:

On Thu, Nov 10, 2022 at 07:25:21PM +0100, Florian Weimer via Gcc wrote:
GCC accepts various conversions between pointers and ints and different
types of pointers by default, issuing a warning.

I've been reading the (hopefully) relevant partso f the C99 standard,
and it seems to me that C implementations are actually required to
diagnose errors in these cases because they are constraint violations:
the types are not compatible.

It doesn't need to be a hard error, a warning is a diagnostic message,
which is enough to diagnose a violation of any syntax rule or
constraint.

IIRC, the only case where the compiler _must_ emit a hard error is for
#error.

Hmm, you could be right.

The standard says that constraint violations are not undefiend behavior,
but of course it does not define what happens in the presence of a
constraint violation.  So the behavior is undefined by omission.  This
seems to be a contradiction.


Section 5.1.1.3p1 of the C standard covers diagnostics. (I'm looking at the C11 version at the moment, but numbering is mostly consistent between C standards.) If there is at least one constraint violation or syntax error in the translation unit, then the compiler must emit at least one diagnostic message. That is all that is required.

The C standard does not (as far as I know) distinguish between "error messages" and "warnings", or require that diagnostics stop compilation or the production of output files.

So that means a conforming compiler can sum up all warnings and errors with a single "You did something wrong" message - and it can still produce an object file. It is even allowed to generate the same message when /nothing/ is wrong. The minimum behaviour to be conforming here is not particularly helpful!

Also note that gcc, with default flags, is not a conforming compiler - it does not conform to any language standards. You need at least "-std=c99" (or whatever) and "-Wpedantic". Even then, I think gcc falls foul of the rule in 5.1.1.3p1 that says at least one diagnostic must be issued for a syntax or constraint violation "even if the behaviour is explicitly specified as undefined or implementation-defined". I am not entirely sure, but I think some of the extensions that are enabled even in non-gnu standards modes could contradict that.

I personally think the key question for warnings on things like pointer compatibility depends on whether the compiler will do what the programmer expects. If you have a target where "int" and "long" are the same size, a programmer might use "pointer-to-int" to access a "long", and vice-versa. (This can easily be done accidentally on something like 32-bit ARM, where "int32_t" is "long" rather than "int".) If the compiler may use this incompatibility for type-based alias analysis and optimise on the assumption that the "pointer-to-int" never affects a "long", then such mixups should by default be at least a warning, if not a hard error. The primary goal for warnings and error messages must be to stop the programmer writing code that is wrong and does not do what they expect (as best the compiler can guess what the programmer expects).

The secondary goal is to help the programmer write good quality code, and avoid potentially risky constructs - things that might work now, but could fail with other compiler versions, flags, targets, etc. It is not unreasonable to have warnings in this category need "-Wall" or explicit flags. (I'd like to see more warnings in gcc by default, and more of them as errors, but compatibility with existing build scripts is important.)


I assumed that there was a rule similar to the the rule for #error for
any kind of diagnostic, which would mean that GCC errors are diagnostic
messages in the sense of the standard, but GCC warnings are not.

I believe that both "error" and "warning" messages are "diagnostics" in the terms of the standard.

As I said above, the minimum requirements of the standard provide a very low bar here. A useful compiler must do far better (and gcc /does/ do far better).


I wonder how C++ handles this.

Thanks,
Florian



Reply via email to