From mboxrd@z Thu Jan 1 00:00:00 1970 From: Al Viro Date: Tue, 17 Mar 2015 18:19:15 +0000 Subject: [Cluster-devel] [RFC PATCH 1/5] new helper: iov_iter_rw() In-Reply-To: <20150317093151.GS20767@twin.jikos.cz> References: <34dc78b262546e9343e0ed872232a97f5eaa5f15.1426502566.git.osandov@osandov.com> <20150316173605.GX29656@ZenIV.linux.org.uk> <20150317093151.GS20767@twin.jikos.cz> Message-ID: <20150317181910.GK29656@ZenIV.linux.org.uk> List-Id: To: cluster-devel.redhat.com MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit On Tue, Mar 17, 2015 at 10:31:51AM +0100, David Sterba wrote: > Agreed, but the proposed define is rather cryptic and I was not able to > understand the meaning on the first glance. > > > #define iov_iter_rw(i) ((0 ? (struct iov_iter *)0 : (i))->type & RW_MASK) > > This worked for me, does not compile with anything else than > 'struct iov_iter*' as i: > > #define iov_iter_rw(i) ({ \ > struct iov_iter __iter = *(i); \ > (i)->type & RW_MASK; \ > }) > > The assignment is optimized out. ... and you are getting a) use of rather lousy gccism when plain C would do b) double evaluation since you've got it wrong (should've been __iter.type & RW_MASK, if you do it that way). As it is, if argument has any side effects, your variant will trigger those twice - even if the destination of the assignment is never used, the side effects remain. I agree that it could use /* use ?: for typechecking */, but let's not go into ({...}) land unless we absolutely have to.