Marking select(2) as restrict

Jilles Tjoelker jilles at stack.nl
Thu Feb 22 21:27:48 UTC 2018


On Wed, Feb 21, 2018 at 03:27:21PM -0500, Garrett Wollman wrote:
> <<On Wed, 21 Feb 2018 22:10:02 +0200, Konstantin Belousov <kostikbel at gmail.com> said:

> > Undefined != broken, whatever some compiler vendors try to bluff.

> No, undefined behavior means the application is wrong.  Literally
> anything may happen; the compiler does not enter into it.  The
> compiler is not involved when you free() a pointer into the stack, or
> pass a null pointer into a library routine that unconditionally
> dereferences it, or update a string literal; nor is it involved when
> you pass pointers that alias to a library routine that expects them to
> point to different objects.

> In the particular case of select(), there are no guarantees as to the
> order in which the fd_set objects pointed to by readfds, writefds, and
> exceptfds will be updated, so applications which alias them are
> clearly wrong and have been since this interface was introduced in
> 4.2BSD.

They are wrong, but get away with it if they do not care about the value
stored into the fd_set object.

Furthermore, adding or removing a restrict qualifier on a parameter does
not make the function types incompatible (just like adding or removing a
const or volatile qualifier on a parameter; but those are generally used
behind a pointer which does make the function type incompatible).
Therefore, it would be quite subtle for a missing restrict qualifier to
break a build.

Although the restrict qualifier imposes restrictions on the pointers the
caller can pass, undefined behaviour only results when the callee
dereferences them in disallowed ways (some compilers have bugs that make
them assume the pointers differ even when never dereferenced for
writing). Per the C standard, when the compiler sees aliasing pointers
being passed as restrict pointers to an unknown function, it will have
to assume the callee only dereferences them in permitted ways (such as
not at all, only one of them or only for reading) and can therefore not
optimize anything.

A blog post about -Wrestrict (which was added in GCC 7) at
http://excursionsingcc.blogspot.nl/2016/12/wrestrict.html confirms that
the warning can emit false positives.

The actual implementation of select() in libc only passes along its
arguments to code the compiler cannot see. Therefore, this cannot be
optimized either.

-- 
Jilles Tjoelker


More information about the freebsd-standards mailing list