From owner-freebsd-hackers@freebsd.org Sun Feb 25 23:32:08 2018 Return-Path: Delivered-To: freebsd-hackers@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 46A1FF32C0B for ; Sun, 25 Feb 2018 23:32:08 +0000 (UTC) (envelope-from marklmi26-fbsd@yahoo.com) Received: from sonic301-32.consmr.mail.ne1.yahoo.com (sonic301-32.consmr.mail.ne1.yahoo.com [66.163.184.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id C9E7876BCF for ; Sun, 25 Feb 2018 23:32:07 +0000 (UTC) (envelope-from marklmi26-fbsd@yahoo.com) X-YMail-OSG: z5KulQYVM1lgjp2MoWXlPy8ZJGIVip8A6.tbhkTTNOVBQ9h0e8ZzxdPAupJb0_x f6Kv1iETNsHJNOb.AcTPMWNcdT34qCpcUrXGi5gDEQM34dzCeF_DoEoj4zv_ZVNWazPNANcCvOot YAvHr80ubUhkqwA2tSW2ANLQLX9ietS6hYQHRjUFBKn_MAhAn8GDJl632fqahHVyaVjkh3FH2ufH YkCP4lSzTzzjwww7kk5qSP_hW_sUNqUJWbHb.uoHVFIIKBlzFDroGCzOUxbuZigJVDHTVH03EtnI pcdZB9GbZKK84IS.P.5e.tH7vDsHOJUzDoZKk7gyuNf6Wzx6p7zhiy1D6Q.AlalqxHDtqVD_.ORW i7omnaLqtCZFvDKzZMKxT6BwmnjNPDEgtOlIn4uSDpAIjgAeUR3lBmlu0_L3KP4qUkohzAVxUW44 bb5ggR6Xv9AgNcmoswSrAG6.5Cry7ie6Cq.JbFdjx4zss0rfYMu6zBh4vLE4gLMzHMS8v Received: from sonic.gate.mail.ne1.yahoo.com by sonic301.consmr.mail.ne1.yahoo.com with HTTP; Sun, 25 Feb 2018 23:32:01 +0000 Received: from smtp226.mail.ne1.yahoo.com (EHLO [192.168.1.25]) ([10.218.253.215]) by smtp410.mail.ne1.yahoo.com (JAMES SMTP Server ) with ESMTPA ID ca9ce8c4b86d225e30f2b4ca91ae9c8d; Sun, 25 Feb 2018 23:31:57 +0000 (UTC) Content-Type: text/plain; charset=us-ascii Mime-Version: 1.0 (Mac OS X Mail 11.2 \(3445.5.20\)) Subject: Re: Marking select(2) as restrict From: Mark Millard In-Reply-To: <20180225214813.776a9f58@kalimero.tijl.coosemans.org> Date: Sun, 25 Feb 2018 15:31:56 -0800 Cc: Konstantin Belousov , Eitan Adler , Kevin Lo , FreeBSD Standards , FreeBSD Hackers Content-Transfer-Encoding: quoted-printable Message-Id: <2909E983-953A-4463-959C-F3C386BC6C9A@yahoo.com> References: <20180221032247.GA81670@ns.kevlo.org> <20180221104400.GU94212@kib.kiev.ua> <20180222112752.10da7e51@kalimero.tijl.coosemans.org> <20180222105608.GE94212@kib.kiev.ua> <20180225214813.776a9f58@kalimero.tijl.coosemans.org> To: Tijl Coosemans X-Mailer: Apple Mail (2.3445.5.20) X-BeenThere: freebsd-hackers@freebsd.org X-Mailman-Version: 2.1.25 Precedence: list List-Id: Technical Discussions relating to FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 25 Feb 2018 23:32:08 -0000 On 2018-Feb-25, at 12:48 PM, Tijl Coosemans wrote: > On Thu, 22 Feb 2018 12:56:08 +0200 Konstantin Belousov 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)