<div dir="ltr">On Tue, Nov 5, 2013 at 11:19 AM, David Chisnall <span dir="ltr"><<a href="mailto:David.Chisnall@cl.cam.ac.uk" target="_blank">David.Chisnall@cl.cam.ac.uk</a>></span> wrote:<br><div class="gmail_extra">
<div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="im">On 5 Nov 2013, at 18:19, Reid Kleckner <<a href="mailto:rnk@google.com">rnk@google.com</a>> wrote:<br>

<br>
> IMO extern "C" is a clear indication that the user wants to interoperate between C and C++.  clang should have this warning on by default in extern "C" contexts.<br>
<br>
</div>The problem is that the compiler only sees the extern "C" when compiling in C++ mode, but the author of the header most likely compiles predominantly in C mode.<br></blockquote><div><br></div><div>I'm honestly not worried about this. If someone is writing a header that they expect to be usable from language modes X, Y, and Z, and they neither try building the code in all of those language modes nor telling us they intend to build the code in those modes (by using -Wc++-compat, for instance), I think it's reasonable to say that they are beyond our help.</div>
<div><br></div><div>The -Wc++-compat warning we already have is nice, but we should probably also warn (with an on-by-default warning!) if this occurs in an extern "C" block in C++.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

It would be nice to have an annotation that could be added to a header that would let the compiler (or some tool) automatically check that it would work if compiled in either C or C++ mode.<br>
<br>
To check properly, you'd need to parse it as both C and C++ and do the full range of checks, ideally also checking that symbols have the same linkage in both versions.<br>
<br>
For a simple example of why this is difficult, in FreeBSD libc (and many other libc implementations) we have __BEGIN_DECLS and __END_DECLS macros.  These expand to extern "C" { and } respectively in C++ mode, or to nothing in C mode.  Just looking for extern "C", even inside an #ifdef, won't help you.<br>

<br>
I'd like to see such a tool, and ideally one that would let you specify what language dialects you expect a header to be valid for.  For example:<br>
<br>
#pragma clang valid_languages c99, c89, gnu99, gnu++99<br>
<br>
Although ideally something other than a pragma, so that we could have a __VALID_C and __VALID_CXX macros that would expand to something different depending on the compiler and the language dialects that we care about.<br>

<br>
The tool would then check trivial compatibility (does this file parse as valid code in all of these dialects), but also less trivial properties, including:<br>
<br>
- Are all C structs declared in it POD types in C++?<br></blockquote><div><br></div><div>We already check that types passed to / returned from extern "C" functions are C-compatible (POD is not the right thing to check). It would make sense to check the zero-sized struct case here too.</div>
<div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
- Are all C functions extern "C" linkage in C++?<br></blockquote><div><br></div><div>We can only do this check if we're building in C++, but if we're building in C++, this check is not appropriate, because cross-language headers frequently declare extra or different function signatures when built in C++ (for instance, an overload set of 'abs' instead of a single function). I think this would have too much noise to be really useful.</div>
</div></div></div>