Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 25 Feb 2018 20:40:16 -0800
From:      Mark Millard <marklmi26-fbsd@yahoo.com>
To:        Bruce Evans <brde@optusnet.com.au>
Cc:        Tijl Coosemans <tijl@freebsd.org>, FreeBSD Standards <freebsd-standards@freebsd.org>, FreeBSD Hackers <freebsd-hackers@freebsd.org>, Kevin Lo <kevlo@freebsd.org>
Subject:   Re: Marking select(2) as restrict
Message-ID:  <1A2830F4-A00B-4C56-8D28-C46715DC7C9E@yahoo.com>
In-Reply-To: <20180226135457.B1203@besplex.bde.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> <2909E983-953A-4463-959C-F3C386BC6C9A@yahoo.com> <20180226135457.B1203@besplex.bde.org>

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


On 2018-Feb-25, at 7:45 PM, Bruce Evans <brde at optusnet.com.au> wrote:

> On Sun, 25 Feb 2018, Mark Millard via freebsd-standards wrote:
>=20
>> On 2018-Feb-25, at 12:48 PM, Tijl Coosemans <tijl at FreeBSD.org> =
wrote:
>>=20
>>> 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.
>>=20
>> 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.
>>=20
>> A prototype that would make h's restrictions clearer is
>> one that reports that q and r are not used to modify
>> memory:
>>=20
>> void h(int n, int * restrict p, int const * restrict q, int const * =
restrict r);
>>=20
>> 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.)
>=20
> I think the example intentionally leaves out 'const'.  I think const
> already prevents aliasing.  'restrict' prevents it even more.  Using
> the combination in the exaple would make it less clear what the
> 'restrict' part does.

Agreed: the combination would make the example less clear
about restrict. So, agreed: likely deliberate for specifying
just restrict's semantics. I would not suggest my alternate
h prototype for that example in the standard: different
purposes served.

> . . . restrict is not needed for the input-only
> args since const suffices.=20

Here you lost me.

With q and r having both the const and the restrict,
updates to p's "objects" can not change the
"object(s)" q and r validly can be used to access.
That can be important.

Without the "restrict" for q and r (but still
having the const for each) it is valid for updates
to p's "objects" to change what q and r then can
validly access.

The 2 restrict's in question do not seem redundant
to me as far as the prototype goes. They may enable
optimizations in some architectures: more order of
operation independence so more reordering possible.

A more general context could still require words
describing requirements, words beyond the restrict
and const use. I would not claim that adding const
where it fits would make all contexts well described.
This one just happened to be nicer for the person
reading the prototype. (But it would makes for a
worse specification of restrict of itself to have
the const's in place in example 3.)

=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?1A2830F4-A00B-4C56-8D28-C46715DC7C9E>