Sujet : Re: Computer architects leaving Intel...
De : bl1-thispartdoesnotbelonghere (at) *nospam* gmx.com (Bernd Linsel)
Groupes : comp.archDate : 31. Aug 2024, 12:10:22
Autres entêtes
Organisation : A noiseless patient Spider
Message-ID : <vautmu$vr5r$1@dont-email.me>
References : 1 2 3 4 5 6
User-Agent : Betterbird (Linux)
On 31.08.24 11:24, Thomas Koenig wrote:
Bernd Linsel <bl1-thispartdoesnotbelonghere@gmx.com> schrieb:
The clang/gcc maintainers' POV violates the first part of Postel's Law:
>
Be liberal in what you accept, and conservative in what you send.
>
Life would be a lot easier if they just provided a -WUB option that
warns and explains *any* construct that the compiler may regard as UB.
Maybe a bit more elaborate:
#include <stdio.h>
int main()
{
int i;
scanf("%d", &i);
return 0;
}
Should this be warned about?
[corrected sscanf -> scanf]
Why? This "program" has the purpose to read one line, presumably containing an integer number, from stdin and ignore it. No UB anywhere.
It does accept an empty line as well as 3432 MB of garbage, and even an integer without leading space, but always returns true.
Scanf's man page does not state anything about warn-unused-result, and it's input parsing is clearly described.
I would not complain if the compiler would deliver something that's roughly equivalent to
int main(void)
{
(void)scanf("%*s");
return 0;
}
while
int main(void)
{
return 0;
}
would be inacceptable.
Or what about
void foo(int *a)
{
*a ++;
}
Two possible cases of undefined behavior here: a could be an
invalid pointer, and the arithmetic operation could overflow.
The result of the pointer increment is never used, so the compiler will warn and not compile any increment instruction nonetheless.
Furthermore, as *a is not declared volatile, the read operation is superfluous. A call to foo() may thus legally result in:
<nothing>,
but a still better result would be:
foo(x) -> assert(__builtin_expect(x != NULL, 1)).
Additionally, I'd expect at least 2 warnings:
- result of pointer increment `a++` never used
- result of variable access `*a` never used.
GCC provides means like e.g. the nonnull() attribute, and even if that were not available, it is good practice to assert() pointer arguments -- or check and return an error code -- at the beginning of the function body, if you expect to be called from arbitrary (library user) code.
Furthermore, to provide hints to the compiler, you can always write something like:
if (a == NULL) __builtin_unreachable();
Commonly, one instruments that as:
#define ASSUME(cond) \
do { \
if (!__builtin_expect(!(cond),0)) \
__builtin_unreachable(); \
} while (0)
Maybe my previous post was not clear enough: It's not a general UB detector that I'd like to have integrated into the compiler (there are static checker tools available that can nearly perfectly do that); instead, I'd like to get a warning when the compiler does something other than you would expect when reading the code in a "do what I mean" manner.
-- Bernd Linsel