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>