<html><head></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><br><div><div>On Aug 26, 2011, at 1:39 PM, David Blaikie wrote:</div><blockquote type="cite">On Fri, Aug 26, 2011 at 11:56 AM, Douglas Gregor <<a href="mailto:dgregor@apple.com">dgregor@apple.com</a>> wrote:<br>><br><br>> Yes, 0 should be acceptable as a pointer literal, as should 0L. This is<br>
> convention for a large number of projects and programmers.<br><br><div>Agreed for C++93.<br><div><br>For the C++11 case here's my attempt at a parallel to existing warnings -Wparentheses. When this warning was added, I assume lots of people would've had to change their code (or suppress the warning). It was added to help detect a common source of user error by imposing a new (well, probably partially adopted from some existing developers conventions, I assume), somewhat arbitrary (not a standard construct, just an arbitrary choice of syntax to indicate "I did this deliberately") syntax to express developer intent to the compiler (& other developers) so the compiler could more accurately detect possible errors.<br>
<br><span class="Apple-style-span" style="font-family: 'Times New Roman'; font-size: medium; "><pre><span class="terminalStyle1" style="font-weight: bold; ">foo.c:5:9: </span><span class="terminalStyle0"></span><span class="terminalStyle135" style="color: rgb(255, 0, 255); font-weight: bold; ">warning: </span><span class="terminalStyle0"></span><span class="terminalStyle1" style="font-weight: bold; ">using the result of an assignment as a condition without parentheses [-Wparentheses]
</span><span class="terminalStyle0">  if (a = b)
</span><span class="terminalStyle132" style="color: green; font-weight: bold; ">      ~~^~~</span></pre></span><div>That seems equivalent to suggesting NULL instead of 0 in pointer contexts in C++98, really. If you do that, then the compiler knows what you mean & can help you check that what you mean is what you actually got. (by checking NULL is used always and only in pointer contexts)<br></div></div></div></blockquote><div><br></div><div>Two big differences here:</div><div><br></div><div>  1) if (a = b) is very likely to be an error</div><div>  2) GCC 4.3 introduced -Wparentheses with roughly the same semantics as Clang eventually implemented, so the convention was pre-established</div><div><br></div><blockquote type="cite"><div><div><div>The C++11 case of suggesting nullptr seems even stronger than the case for -Wparentheses, in this case nullptr is a language-provided construct designed for the purpose.</div></div></div></blockquote><div><br></div>… that has seen very little use in the field. The C++'0x standard hasn't been officially published yet, so it's way to early to use it as the basis for establishing convention.</div><div><br><blockquote type="cite"><div><div><div><span class="Apple-style-span" style="font-family: arial, sans-serif; font-size: 13px; background-color: rgb(255, 255, 255); "><div style="display: inline !important; ">> You're assuming that programmers want to migrate all of their code to C++0x and its idioms. </div></span></div><div><span class="Apple-style-span" style="font-family: arial, sans-serif; font-size: 13px; background-color: rgb(255, 255, 255); ">
<div><br></div><div>Not entirely - I'm assuming that it's the 'right' way to write C++0x and developers who want to write in some limited subset of C++0x can suppress it. If C++0x has been chosen, it makes sense to me to provide the best diagnostics we can for writing C++0x, not a subset of it. If using nullptr means we can diagnose more pointer mis-usage (indeed, as hard compiler errors, in fact - once you've switched to nullptr you won't just get a silence when you compare a pointer to 0 thinking it was an integer, you'll get an error) it seems we'd be doing a disservice to C++0x developers not to tell them they were being ambiguous & that the compiler won't be helping them as much as it could.</div></span></div></div></div></blockquote><div><br></div>You're advocating a coding style that favors nullptr over 0. That's fine, and for a purely C++0x code base I *might* agree with you (although 0 is so much shorter than nullptr). However, the use of 0 rather than nullptr is not a good indication that there is actually a problem with the code, so we're outside the domain of what a compiler should do.</div><div><br><blockquote type="cite"><div><div><div><span class="Apple-style-span" style="font-family: arial, sans-serif; font-size: 13px; background-color: rgb(255, 255, 255); "><div>It's probably one of the cheapest (especially with a fixup) migrations to make when compiling code as C++0x. The first 0x feature pretty much any compiler will implement, so I'm not sure many people would choose to compile as C++0x yet resist updating to a construct that helps diagnose bugs and expresses the author intent more clearly (to both other developers and the compiler itself).</div></span></div></div></div></blockquote><div><br></div><div>Lots of code bases will be compiling both as C++98 and as C++0x for several years. I build Clang as C++0x with libc++; do you want me changing all of the 0's to nullptr's? The buildbots sure don't want me to.</div><br><blockquote type="cite"><div><div><div><span class="Apple-style-span" style="font-family: arial, sans-serif; font-size: 13px; background-color: rgb(255, 255, 255); "><div>> For the other side of the equation, check out the warning + Fix-It for this code:</div></span><span class="Apple-style-span" style="font-family: arial, sans-serif; font-size: 13px; white-space: pre-wrap; background-color: rgb(255, 255, 255); ">>        struct Point { int x, y; } p = { x: 10 };</span></div>
<div><font class="Apple-style-span" face="arial, sans-serif"><span class="Apple-style-span" style="white-space: pre-wrap;"><br></span></font></div><div><font class="Apple-style-span" face="arial, sans-serif"><span class="Apple-style-span" style="white-space: pre-wrap;">I agree, this is a much more compelling warning than the one I'm proposing - and I'm sure there are many other better/less ambiguous warnings than nullptr. My point is that there are many /less/ compelling warnings too (though I don't know which of those are consistent with your philosophy & which aren't).</span></font></div>
<div><font class="Apple-style-span" face="arial, sans-serif"><span class="Apple-style-span" style="white-space: pre-wrap;"><br></span></font></div><div><font class="Apple-style-span" face="arial, sans-serif"><span class="Apple-style-span" style="white-space: pre-wrap;">Side note:</span></font></div>
<div><span class="Apple-style-span" style="font-family: 'Times New Roman'; font-size: medium; "><pre><span class="terminalStyle1" style="font-weight: bold; ">/tmp/webcompile/_1251_0.c:1:37: </span><span class="terminalStyle0"></span><span class="terminalStyle135" style="color: rgb(255, 0, 255); font-weight: bold; ">warning: </span><span class="terminalStyle0"></span><span class="terminalStyle1" style="font-weight: bold; ">use of GNU old-style field designator extension [-Wgnu-designator]
</span><span class="terminalStyle0">struct Point { int x, y; } p = { x: 10 };
</span><span class="terminalStyle132" style="color: green; font-weight: bold; ">                                 ~~ ^
</span><span class="terminalStyle0"></span><span class="terminalStyle032" style="color: green; ">                                 .x = </span></pre></span></div><div>Shouldn't that ^ be below the x, not the 10? like this:</div>
<div><br></div><div><span class="Apple-style-span" style="font-family: 'Times New Roman'; font-size: medium; "><pre><span class="terminalStyle1" style="font-weight: bold; ">/tmp/webcompile/_1251_0.c:1:37: </span><span class="terminalStyle0"></span><span class="terminalStyle135" style="color: rgb(255, 0, 255); font-weight: bold; ">warning: </span><span class="terminalStyle0"></span><span class="terminalStyle1" style="font-weight: bold; ">use of GNU old-style field designator extension [-Wgnu-designator]
</span><span class="terminalStyle0">struct Point { int x, y; } p = { x: 10 };
</span><span class="terminalStyle132" style="color: green; font-weight: bold; ">                                 ^~ 
</span><span class="terminalStyle0"></span><span class="terminalStyle032" style="color: green; ">                                 .x = </span></pre></span></div></div></div></blockquote><div>Yes, that'd be better. Patch welcome :)</div><br><blockquote type="cite"><div><div>> > I'd say all uses of NULL in non-pointer contexts should be caught.<br>
><br>> I'm fine with this.</div><div><br></div><div>Ok, great! I can do that, I think. Any idea how this would work with the existing -Wnull-arithmetic warning which is a subset of this? (it disallows "NULL + 2" and "NULL < 3" but doesn't stop "int i = NULL;" (or "void foo(int); foo(NULL)"))<br></div></div></blockquote><div><br></div>It's easy to add diagnostic subgroups. -Wnull-arithmetic can be a subgroup of some new group covering NULL-as-integer warnings.</div><div><br><blockquote type="cite"><div><div>Is a fixit to nullptr applicable here (in C++0x) similar to the diff I provided for the use of 'false' in pointer contexts to suggest nullptr in C++0x? Or should the output remain agnostic to null pointer literals in C++11?</div></div></blockquote><div><br></div><div>I could live with suggesting nullptr in C++0x and NULL (if available) or 0 otherwise.</div><br><blockquote type="cite"><div><div>>><br>>> The question is whether such a warning will produce too much noise; the<br>>> only way to figure that out is to implement it and run it across a pile of<br>>> code.<br>><br>> Fair enough. Is there an appropriate reference set/process that should be<br>
> used - is this the sort of thing where we would add the warning, on by<br>> default, see what the buildbots/etc cough up, or is there some way to<br>> replicate all that test coverage locally to avoid randomizing the<br>
> bots/developers?<br>><br>> There's no reference set, save LLVM and Clang itself. Different people use<br>> their own favored projects to see how a warning fares.<br><br></div></div><div>Ok - though that won't help with C++0x warnings like I'm suggesting, unfortunately. I wonder if there are any major projects compiling as C++0x currently.</div>
</blockquote><br></div><div>Well, you can compile LLVM and Clang as C++0x. </div><div><br></div><div><span class="Apple-tab-span" style="white-space:pre"> </span>- Doug</div><br></body></html>