From owner-freebsd-hackers@freebsd.org Tue Sep 13 21:44:11 2016 Return-Path: Delivered-To: freebsd-hackers@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 6E14ABD9700 for ; Tue, 13 Sep 2016 21:44:11 +0000 (UTC) (envelope-from jilles@stack.nl) Received: from mx1.stack.nl (relay02.stack.nl [IPv6:2001:610:1108:5010::104]) (using TLSv1 with cipher DHE-RSA-CAMELLIA256-SHA (256/256 bits)) (Client CN "mailhost.stack.nl", Issuer "CA Cert Signing Authority" (not verified)) by mx1.freebsd.org (Postfix) with ESMTPS id 3DC8EC8E for ; Tue, 13 Sep 2016 21:44:11 +0000 (UTC) (envelope-from jilles@stack.nl) Received: from snail.stack.nl (snail.stack.nl [IPv6:2001:610:1108:5010::131]) by mx1.stack.nl (Postfix) with ESMTP id 36945358C64; Tue, 13 Sep 2016 23:44:08 +0200 (CEST) Received: by snail.stack.nl (Postfix, from userid 1677) id 0BB5628494; Tue, 13 Sep 2016 23:44:08 +0200 (CEST) Date: Tue, 13 Sep 2016 23:44:07 +0200 From: Jilles Tjoelker To: twilight Cc: freebsd-hackers@FreeBSD.org Subject: Re: What is the point in expression: !!var ? Message-ID: <20160913214407.GA96125@stack.nl> References: <7bf5cd37-6436-8cec-74e3-f0856bcc807c@openmailbox.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <7bf5cd37-6436-8cec-74e3-f0856bcc807c@openmailbox.org> User-Agent: Mutt/1.5.21 (2010-09-15) X-BeenThere: freebsd-hackers@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Technical Discussions relating to FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 13 Sep 2016 21:44:11 -0000 On Tue, Sep 13, 2016 at 07:54:31PM +0000, twilight wrote: > I'm digging through FreeBSD cppcheck scan report with hope to catch some > bugs. > I've came along a line: > c = cond(token, val, yylex(), noeval | !!a); > What's the point in using !! twice? Can it be deleted? > Here is the context: > static arith_t cond(int token, union yystype *val, int op, int noeval) > { > arith_t a = or(token, val, op, noeval); > arith_t b; > arith_t c; > > if (last_token != ARITH_QMARK) > return a; > > b = assignment(yylex(), noeval | !a); > > if (last_token != ARITH_COLON) > yyerror("expecting ':'"); > > token = yylex(); > *val = yylval; > > c = cond(token, val, yylex(), noeval | !!a); > > return a ? b : c; > } The intent of the code is more accurately captured by c = cond(token, val, yylex(), noeval || a != 0); (omitting != 0 would match this file's style better) I think the author of this code did not write that because many compilers generate slightly smaller code for the version with |. With stable/10's clang 3.4.1 on amd64 the difference is 16 bytes if this change is applied to all conditions in arith_yacc.c. The code is from the dash shell, which contains many tricks to make the generated code smaller. As noted by others, just removing !! is wrong. For example, it would break echo "$((0x100000000 ? 2 : 1 / 0))". -- Jilles Tjoelker