Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 25 Feb 2018 15:31:56 -0800
From:      Mark Millard <marklmi26-fbsd@yahoo.com>
To:        Tijl Coosemans <tijl@FreeBSD.org>
Cc:        Konstantin Belousov <kostikbel@gmail.com>, Eitan Adler <lists@eitanadler.com>, Kevin Lo <kevlo@freebsd.org>, FreeBSD Standards <freebsd-standards@freebsd.org>, FreeBSD Hackers <freebsd-hackers@freebsd.org>
Subject:   Re: Marking select(2) as restrict
Message-ID:  <2909E983-953A-4463-959C-F3C386BC6C9A@yahoo.com>
In-Reply-To: <20180225214813.776a9f58@kalimero.tijl.coosemans.org>
References:  <CAF6rxg=h_oMiUu7P=GAOQf_OySQM2w31hg6Kas%2B3jeEM3qq_Cg@mail.gmail.com> <CAF6rxgnt9c0n8i-nHQwoKGbZKF2hM5AZqEJnz0CLo26XOO4_sg@mail.gmail.com> <20180221032247.GA81670@ns.kevlo.org> <CAF6rxg=WwqeBnmJzfOZgtwrYesXPfvJFeaVmQwtTa_89_sxaJg@mail.gmail.com> <CANCZdfo46bhfaRpbqOmJjk4%2B=1R2c5kvmrJPENaxNgK==5M4kg@mail.gmail.com> <CAF6rxg=wNVgDUF9o744ngmzPNeHB3hqdrLufy=yS3D4osczxFQ@mail.gmail.com> <20180221104400.GU94212@kib.kiev.ua> <20180222112752.10da7e51@kalimero.tijl.coosemans.org> <20180222105608.GE94212@kib.kiev.ua> <20180225214813.776a9f58@kalimero.tijl.coosemans.org>

next in thread | previous in thread | raw e-mail | index | archive | help

On 2018-Feb-25, at 12:48 PM, Tijl Coosemans <tijl at FreeBSD.org> wrote:

> On Thu, 22 Feb 2018 12:56:08 +0200 Konstantin Belousov <kostikbel at =
gmail.com> wrote:
>> Consider the recently changed devd code:
>> 	select(n + 1, &fd, &fd, &fd);
>> There, compiler can see that restrict is applied to arguments which =
are
>> given same values.  Since this leads to the self-contradicting =
statement
>> 	fd !=3D fd
>> which cannot be true, compliler in its optimizing wisdom can assume =
that
>> the code is never executing and remove it.  I do not know whether =
clang
>> actually makes such transformation, but it does not sound unfeasible
>> looking at its other advances.
>=20
> There's an example in the C99 standard that indicates such a call is =
not
> necessarily undefined so compilers cannot optimise it away:
>=20
> EXAMPLE 3
> The function parameter declarations
> void h(int n, int * restrict p, int * restrict q, int * restrict r)
> {
> 	int i;
> 	for (i =3D 0; i < n; i++)
> 		p[i] =3D q[i] + r[i];
> }
> illustrate how an unmodified object can be aliased through two =
restricted
> pointers.  In particular, if a and b are disjoint arrays, a call of =
the
> form h(100, a, b, b) has defined behavior, because array b is not =
modified
> within function h.

Good point. In essence the restrictions on the caller can
not be known independently of how the parameters are used
in the called code --something that prototype does not specify.
This does constrain what the compiler can do about potential
aliasing that it might detect.

A prototype that would make h's restrictions clearer is
one that reports that q and r are not used to modify
memory:

void h(int n, int * restrict p, int const * restrict q, int const * =
restrict r);

With such a prototype, it is easier to known that q's "objects"
and r's "objects" both simply must not overlap p's "objects".
(See g from example 2 for its d+50 valid vs. d+1 invalid status.)

Section 7.1 of the C Rationale says:

"The restrict keyword allows the prototype to express what was
previously expressed by words."

But it turns out that not all the words can be eliminated if one
is to know the actual criteria for what the caller is allowed to
do while staying within defined behavior.

There is a lot of wording for which the "example 3"
h(100, a, b, b) example usage being well defined is not
obvious. Such wording is without any specific such context
to reference and tends to assume that all restricted pointers
are used to modify the matching objects (when const does not
prevent such). This need not be the case.

=3D=3D=3D
Mark Millard
marklmi at yahoo.com
( markmi at dsl-only.net is
going away in 2018-Feb, late)




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?2909E983-953A-4463-959C-F3C386BC6C9A>