glibc misc/sys/cdefs.h nonull - typo in comment
Xi Ruoyao
xry111@xry111.site
Wed Apr 12 16:26:48 GMT 2023
On Wed, 2023-04-12 at 16:56 +0100, Jonny Grant wrote:
> Do you think it is risky to have the nonnull attribute in use in glibc?
> Some projects have abandoned attribute nonnull due to the GCC optimizer using the nonnull attribute to remove the runtime null pointer checks.
> https://gitlab.com/gnuwget/wget2/-/issues/200
No because in the C standard & POSIX standard the text is clear that
many arguments just should not be NULL. So the implementation does not
need to check if such an argument is NULL.
If the standard allows an argument to be NULL but there is attribute
nonnull there, it's a bug. Please open a ticket in
https://sourceware.org/bugzilla if you find such a bug. But when there
is no bugs, we have no reason to remove avoid nonnull for "comforting
some people".
> Currently cdefs.h has
>
> /* The nonnull function attribute marks pointer parameters that
> must not be NULL. This has the name __nonnull in glibc,
> and __attribute_nonnull__ in files shared with Gnulib to avoid
> collision with a different __nonnull in DragonFlyBSD 5.9. */
>
> Is it better to clarify this to be something like the following?
>
> /* The nonnull function attribute marks pointer parameters that
> the compiler's optimizer knows will never be NULL. This means NULL checks can be optimized out.
No because such NULL checks which can be removed by nonnull attribute
should not exist in Glibc. If any one exists, it's a bug (CWE-1164
"Irrelevant Code"). Again open a ticket if you find one. But I guess
you won't find any, because such a bug will be rejected by "gcc -Wall -
Werror" and there are many people building Glibc with this.
And the user should not assume any implementation details in Glibc
functions. For example:
size_t
f (const char *s)
{
size_t r = strlen (s);
return s ? r : 0;
}
will do strange things no matter if nonnull is used for strlen. Even if
you remove the nonnull attribute of strlen and expect this thing to
work, the different implementations (in many Glibc ports, heavily
optimized assembly code) can still do unexpected things. The people
writing the implementation of strlen will assume the argument is not
null anyway because the standard says so.
So this is just broken in the nature, regardless of nonnull or not.
OTOH
size_t
f (const char *s)
{
return s ? strlen (r) : 0;
}
is well-defined. The compiler is prohibited from removing the check, no
matter if nonnull is used for strlen. If the compiler removed the
check, it's a bug. Again if there is a bug, report it; but if there is
no bugs, you cannot tell people to "fix" it just because "it seems
risky".
Anyway Glibc (and GCC) are C implementations for real C programs, not
for "allowing people who don't know C to programming in C".
--
Xi Ruoyao <xry111@xry111.site>
School of Aerospace Science and Technology, Xidian University
More information about the Libc-alpha
mailing list