<div dir="ltr"><div>Hello Everyone</div><div> </div><div>The following program exhibits a few interesting things to me regarding clang/gcc/libcxx and maybe also the C/C++ standard.</div><div>I would appreciate anyone's comments on this, particularly those of Richard Smith who has a keen eye on much of this subject area.</div>
<div> </div><div>* If I, take this program:.</div><p>#include <cwchar><br>using namespace std;<br>#include <windows.h></p><div>int main()<br>{<br>}</div><div> </div><div>Then if I compile it on a platform that has Windows.h using libcxx, e.g.</div>
<div>svn co <a href="http://llvm.org/svn/llvm-project/libcxx/trunk">http://llvm.org/svn/llvm-project/libcxx/trunk</a> /libcxx<br>clang++ -nostdinc++ -I/libcxx/include -std=c++11 -O3 -c wc.cpp<br></div><div><div>Then I observe compiler errors with-O3 but with -O0 or no option it compiles without error. The same happens with g++.</div>
<div> </div><div>The example code was actually distilled from compiling with the popular Ninja code base FWIW.</div><div> </div><div>The errors are:</div><div>-------------------------------------------</div><div>// The above program generates errors when compiled.</div>
<div>/* With clang:<br>clang++ -nostdinc++ -I/libcxx/include -std=c++11 -O3 -c wc.cpp<br>wc.cpp:6:23: error: call to 'wcschr' is ambiguous<br>    const wchar_t*p = wcschr(s, L'x');<br>                      ^~~~~~<br>
c:\mingw\bin\..\lib\clang\3.4\../../../x86_64-w64-mingw32/include\wchar.h:840:34: note: candidate function<br>  _CONST_RETURN wchar_t *__cdecl wcschr(const wchar_t *_Str,wchar_t _Ch);<br>                                 ^<br>
/libcxx/include\cwchar:180:49: note: candidate function<br>inline _LIBCPP_INLINE_VISIBILITY const wchar_t* wcschr(const wchar_t* __s, wchar_t __c) {return ::wcschr(__s, __c);}<br>                                                ^<br>
1 error generated.<br>*/</div><div>/* With g++<br>++ -nostdinc++ -I/libcxx/include -std=c++11 -O3 -c wc.cpp<br>wc.cpp: In function 'int main()':<br>wc.cpp:9:37: error: call of overloaded 'wcschr(const wchar_t*&, wchar_t)' is ambiguous<br>
     const wchar_t*p = wcschr(s, L'x');<br>                                     ^<br>wc.cpp:9:37: note: candidates are:<br>In file included from /libcxx/include/iosfwd:90:0,<br>                 from /libcxx/include/string:435,<br>
                 from wc.cpp:2:<br>c:\mingw\x86_64-w64-mingw32\include\wchar.h:840:34: note: wchar_t* wcschr(const wchar_t*, wchar_t)<br>   _CONST_RETURN wchar_t *__cdecl wcschr(const wchar_t *_Str,wchar_t _Ch);<br>                                  ^<br>
In file included from /libcxx/include/string:438:0,<br>                 from wc.cpp:2:<br>/libcxx/include/cwchar:181:49: note: wchar_t* std::__1::wcschr(wchar_t*, wchar_t) <near match><br> inline _LIBCPP_INLINE_VISIBILITY       wchar_t* wcschr(      wchar_t* __s, wchar_t __c) {return ::wcschr(__s, __c);}<br>
                                                 ^<br>/libcxx/include/cwchar:181:49: note:   no known conversion for argument 1 from 'const wchar_t*' to 'wchar_t*'<br>/libcxx/include/cwchar:180:49: note: const wchar_t* std::__1::wcschr(const wchar_t*, wchar_t)<br>
 inline _LIBCPP_INLINE_VISIBILITY const wchar_t* wcschr(const wchar_t* __s, wchar_t __c) {return ::wcschr(__s, __c);}<br>*/<br>-----------------------------------</div><div> </div><div><div>Surprisingly (to me) both clang++ and g++ both fail and succeed in the same circumstances with much the same error messages.<br>
</div></div><div>I am thinking the first problem is that this is a compiler bug in both clang++ and g++ that -O3 should lead to compiler errors when  -O0 or no such option compiles without error?</div><div>Any ideas on this Richard etc.?</div>
<div> </div><div>The second "problem" is about having an error at all. Why?</div><div> </div><div>Howard's initial thoughts were these:</div><div> </div><div>"The function signature wcschr(const wchar_t*, wchar_t) shall be replaced by the two declarations:</div>
<div> const wchar_t* wcschr(const wchar_t* s, wchar_t c);<br> wchar_t* wcschr( wchar_t* s, wchar_t c);</div><div>I.e. if you want to implement this correctly, in both C and C++, the C header <wchar.h> has to #ifdef on __cplusplus and provide the proper wcschr signatures in each branch of that #ifdef. If the C header doesn't do this, the C++ header <cwchar> is left with no option that works 100% of the time and is C++ conforming.</div>
<div>libc++ has a #define: _WCHAR_H_CPLUSPLUS_98_CONFORMANCE_</div><div>If this is defined, libc++ assumes <wchar.h> has accommodated us and is giving us the right signatures. Otherwise libc++ sets up the correct signatures.</div>
<div>In the case that libc++ sets up its own signatures, client code can avoid your ambiguity by choosing the C or C++ signatures with :: or std:: qualifiers.</div><div>This design decision impacts wcschr, wcspbrk, wcsrchr, wcsstr and wmemchr. Also in <cstring> we have _STRING_H_CPLUSPLUS_98_CONFORMANCE_ guarding strchr, strpbrk, strrchr, memchr and strstr for the same issue.</div>
<div>I recommend setting (or not) _WCHAR_H_CPLUSPLUS_98_CONFORMANCE_ and _STRING_H_CPLUSPLUS_98_CONFORMANCE_ in <__config>.<br>"</div><div><div><div> </div><div>Does anyone else share this view and we saying windows.h can't compile without some change to __config to handle code like this? Is that realistic/reasonable or no other choice?</div>
<div>Windows.h is a pretty important header.</div><div> </div><div>Is there a better/other solution than having to change something in __config?</div><div>OriIs there a default we can pick up in some way to make things "just work"? Is that reasonable?</div>
<div> </div><div>My ideal goal in mentioning this beyond identifying if clang++/g++ has a bug in compiling with optimization options, is to kick start a process that enables the above program to compile and link without error as at sometime in the history of computing it would have done so.</div>
<div> </div><div>I appreciate that might not be realistic, but if it is, I'd like to identify how it can be done and which parties should come together to make that happen if it in fact a problem or solvable.</div><div>
 </div><div>FWIW, I have proposed a patch to cfe-commits that just so happens to make this situation "go away" but it wasn't intentional nor the primary goal of the patch and I'd like to understand why this situation is what it is before it gets lost by applying my patch as I think it's interesting and the discussion that might improve things. I suspect my patch might just bring Windows.h in before any using statement or something so that things compile but I may be way of base on that. Still, it shouldn't be affected by optimization levels in either case is my thought.</div>
<div> </div><div>So in summary. 1. is there a compiler bug? 2. is there a way to make the above program just work without changing __config or whatever. Does windows.h need changing or benefit from one relating to this? Or gcc/gnu? If there is something of merit here to be done on this subject, who can bring this together, who?</div>
<div> </div><div>Thanks for your help.</div></div></div><br></div></div>