From: Josh Triplett <josh@freedesktop.org>
To: Al Viro <viro@ftp.linux.org.uk>
Cc: linux-sparse@vger.kernel.org,
Linus Torvalds <torvalds@linux-foundation.org>
Subject: Re: fun with ?:
Date: Tue, 22 May 2007 18:03:31 -0700 [thread overview]
Message-ID: <465392E3.3000300@freedesktop.org> (raw)
In-Reply-To: <20070523000234.GJ4095@ftp.linux.org.uk>
[-- Attachment #1: Type: text/plain, Size: 4946 bytes --]
Al Viro wrote:
> On Tue, May 22, 2007 at 04:24:49PM -0700, Josh Triplett wrote:
>> Makes sense, except that in C you can assign a void pointer to an arbitrary *
>> without a warning, so why can't conditional expressions do the equivalent?
>
> {in sparse it's obviously not true due to address_space, but that hadn't
> affected C standard decisions; the rest applies to standard C}
>
> For one thing, no, you can't (pointers to functions have every right to
> be unrelated to void *). For another, you are not guaranteed that
> conversion from void * to int * will not yield undefined behaviour.
> It is OK if the value of void * is properly aligned; then you know
> that conversion back to void * will give the original pointer. Otherwise
> you are in nasal demon country. The other way round (int * to void *
> to int *) you are always safe.
>
> Rationale: systems that have pointers to words and char smaller than word.
> There you can very well have pointers to void and pointers to less-than-word
> objects bigger than pointers to anything word-sized or bigger (e.g. they
> can be represented as word address + bit offset). Conversion to the latter
> will lose offset and compiler is allowed to throw up on that at runtime.
Go Cray go.
> Moral: void * -> int * may lose parts of value and trigger undefined behaviour;
> int * -> void * loses information about type, is always revertible and always
> safe. In assignment operator it's your responsibility to make sure that
> void * you are converting to int * is properly aligned (anything that started
> its life as int * will be). In ?: C could
> * lose type information, allowing any values (result is void *); if
> you are sure that it's well-aligned, you can cast void * argument to int *
> or cast the result.
> * require the void * argument to be well-aligned, keep the type.
>
> The former makes more sense...
Fair enough.
>>> Again, null pointer constant is not the same thing as null pointer to void.
>> I see. I find it very strange that (void *)0 and (void *)(void *)0 have
>> different behavior. I also find it strange that conditional expressions can't
>> convert void * to an arbitrary pointer as assignment can.
>
> It would be nicer if C had __null__ as the *only* null pointer constant
> (with flexible type) and could refuse to accept anything else. Too late
> for that, unfortunately. As for conversions - see above.
Agreed; that seems far saner. (Or, as long as we wishfully redefine the
original C spec, just NULL or null, sans underscores.)
>>> BTW, there's another painful area: what do we do to somebody who uses
>>> (void *)(69 + 1 - 70) as null pointer constant? Currenly sparse doesn't
>>> recognize it as such; C standard does. IMO the right thing to do is
>>> to add a flag that would switch to full-blown standard rules in that area
>>> ("integer constant expression returning 0" instead of basically "0 in some
>>> layers of ()") and flame to the crisp any wanker caught at actually doing
>>> that. Any suggestions re sufficiently violent warning messages?
>> I didn't know that the C standard actually *required* constant folding.
>> Interesting. Would it add excessively to compilation time to apply the usual
>> Sparse constant folding here? If so, and if you really think this case
>> matters, let's have an option to turn on this constant folding, and warn
>> whenever we see it.
>
> Usual sparse constant folding is _almost_ OK, provided that we play a bit
> with evaluate_expression() and let it decide if subexpression is an integer
> constant expression. No prototype changes, we just get a global flag
> and save/restore it around sizeof argument handling and several other
> places. It's actually pretty easy. And if we get "it is an integer
> constant expression", well, then caller can call expand stuff.
Sounds reasonable to me. Possibly better written as some kind of generic
parse-tree-walking operation, but this approach should work fine.
> "Almost" bit above refers to another bit of insanity, fortunately easily
> handled; we need division by zero to raise no error and just yield "the
> entire thing is not an integer constant expression with value 0". That's
> exactly what longjmp() is for...
$ egrep -r 'setjmp|longjmp' ~/src/sparse/*
$
Let's keep it that way, please. :) Evaluation almost certainly should warn for
a compile-time divide-by-zero regardless, though we don't want to warn twice
for the same expression. With the global "check for integer constant
expression" flag set, if evaluation encounters a compile-time divide-by-zero,
evaluation could just set a divided_by_zero flag. Or something like that.
> Speaking of C standard, if you need access to the current one - yell.
I use http://c0x.coding-guidelines.com/ , which has the C99 spec and some
subsequent updates.
- Josh Triplett
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 252 bytes --]
next prev parent reply other threads:[~2007-05-23 1:04 UTC|newest]
Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-05-19 2:52 fun with ?: Al Viro
2007-05-22 21:40 ` Josh Triplett
2007-05-22 22:46 ` Al Viro
2007-05-22 23:24 ` Josh Triplett
2007-05-23 0:02 ` Al Viro
2007-05-23 0:25 ` Al Viro
2007-05-23 1:05 ` Josh Triplett
2007-05-23 4:53 ` Al Viro
2007-05-23 12:26 ` Morten Welinder
2007-05-23 1:03 ` Josh Triplett [this message]
2007-06-03 1:05 ` Al Viro
2007-05-23 14:25 ` Neil Booth
2007-05-23 14:32 ` Al Viro
2007-05-23 14:47 ` Neil Booth
2007-05-23 15:32 ` Al Viro
2007-05-23 23:01 ` Neil Booth
2007-05-24 0:10 ` Derek M Jones
2007-05-24 0:14 ` Al Viro
2007-05-23 21:16 ` Derek M Jones
2007-05-23 21:59 ` Linus Torvalds
2007-05-23 23:29 ` Derek M Jones
2007-05-24 0:02 ` Al Viro
2007-05-24 0:29 ` Linus Torvalds
2007-05-24 1:36 ` Brett Nash
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=465392E3.3000300@freedesktop.org \
--to=josh@freedesktop.org \
--cc=linux-sparse@vger.kernel.org \
--cc=torvalds@linux-foundation.org \
--cc=viro@ftp.linux.org.uk \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).