Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 13 Sep 2016 23:44:07 +0200
From:      Jilles Tjoelker <jilles@stack.nl>
To:        twilight <pipfstarrd@openmailbox.org>
Cc:        freebsd-hackers@FreeBSD.org
Subject:   Re: What is the point in expression: !!var ?
Message-ID:  <20160913214407.GA96125@stack.nl>
In-Reply-To: <7bf5cd37-6436-8cec-74e3-f0856bcc807c@openmailbox.org>
References:  <7bf5cd37-6436-8cec-74e3-f0856bcc807c@openmailbox.org>

next in thread | previous in thread | raw e-mail | index | archive | help
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



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20160913214407.GA96125>