[cfe-dev] Clang-cl.exe and the VC++ preprocessor
Edward Diener
eldlistmailingz at tropicsoft.com
Fri Jul 11 13:49:03 PDT 2014
On 7/11/2014 1:12 PM, Richard Smith wrote:
> On Fri, Jul 11, 2014 at 8:32 AM, Jonathan 'Rynn' Sauer
> <jonathan.sauer at gmx.de
> <mailto:jonathan.sauer at gmx.de>> wrote:
>
> Hello,
>
> > Also it's worth pointing out that the idea is not to emulate VC++
> in every respect. Only in every respect where not doing so will
> break vast amounts of code. There are plenty of places where not
> emulating VC++ will *fix* vasts amounts of code. I imagine the goal
> is to depart with VC++ in those respects.
> >
> > There are examples where not emulating VC++'s bugs means **we
> can't even include standard windows headers**. Surely we agree that
> a Windows compiler that cannot include <windows.h> would not be
> particularly useful.
>
> Could it be an option to limit the emulation of VC++'s preprocessor
> to system headers and macros defined
> there, similar to how clang suppresses warnings in these cases?
>
>
> I don't think so, no. Clang defines _MSC_VER, so code that has separate
> preprocessor magic for cl.exe versus everything else should use the
> cl.exe path. As a result, we'd break such code if we didn't act like cl.exe.
>
>
> In boost's case, the problem is that
>
> http://www.boost.org/doc/libs/1_55_0/boost/preprocessor/seq/detail/binary_transform.hpp
>
> does not take the MSVC-preprocessor-compatible code path, because:
>
> http://www.boost.org/doc/libs/1_55_0/boost/preprocessor/config/config.hpp
>
> ... explicitly shoots itself in the foot:
>
> # if defined _MSC_VER && _MSC_VER >= 1400 && !(defined __EDG__ ||
> defined __GCCXML__ || defined __CUDACC__ || defined __PATHSCALE__ ||
> defined __clang__ || defined __DMC__ || defined __CODEGEARC__ || defined
> __BORLANDC__ || defined __MWERKS__ || defined __SUNPRO_CC || defined
> __HP_aCC || defined __MRC__ || defined __SC__ || defined __IBMCPP__ ||
> defined __PGI)
> # define BOOST_PP_VARIADICS_MSVC 1
> # endif
>
> I'm not sure what that list of compilers is for (if _MSC_VER is defined,
> why don't you assume the compiler acts like MSC?), but removing "||
> defined __clang__" from the list should fix the issue.
Before I answer you about Boost PP I first want to apologize to
everybody about getting so heated about clang-cl emulating a VC++
preprocessor bug. I have my reasons, as I think everyone could see, for
not wanting clang to emulate the VC++ preprocessor in any way but I
admit from the clang-cl bug report I looked at (
http://llvm.org/bugs/show_bug.cgi?id=14981 ) that trying to process the
VC11 header file xstddef with a conforming C++ standard preprocessor
will not work. So I do understand why it was necessary to emulate a VC++
preprocessor bug in order to process the file.
The code you have mentioned above only deals with variadic macro support
in Boost PP. If you look more closely at it variadic macro support is
always turned on for clang.
As for C++ preprocessor support in Boost PP clang gets the
BOOST_PP_CONFIG_STRICT() flag, denoting a C++ standard supporting
compiler and not the BOOST_PP_CONFIG_MSVC() when using clang-cl. The
first and simplest reason for this was the very reasonable assumption
that clang is producing a C++ standard conformant preprocessor. But the
secondary reason for this, even assuming that the clang-cl preprocessor
must work to some extent as if it were VC++, is that Boost PP support
for VC++ has a huge number of workarounds for various VC++ preprocessor
"bugs" which cause VC++ not to be able to expand macros in the correct
way for a C++ standard conforming preprocessor. The greater number of
those workarounds were crafted by Paul Mensonides when he designed and
wrote the Boost PP library. I crafted a few when working with Paul to
add variadic macro support to Boost PP, and even more recently on the
'develop' branch to solve some more VC++ related preprocessor issues
with variadic macros.
We could obviously change the code very easily to have clang-cl act like
the VC++ preprocessor in every respect by simply setting the
BOOST_PP_CONFIG_MSVC() flag for clang-cl. But it will then be involved
in all the workarounds for VC++ and I have no idea "a priori" if these
VC++ workarounds in Boost PP for clang-cl will make things any better.
My guess is that it will make things much worse. Please try to realize
that the one workaround I have seen in clang-cl to solve the 14981 bug
above is just a drop in the bucket of all the C++ preprocessor
non-conformant behavior of VC++. And I highly doubt whether clang-cl
emulates all the "bugs" in the VC++ preprocessor. Nor is it even
possible in most cases to see what the VC++ preprocessor is doing when
it does not expand macros correctly in complicated situations of
preprocessor metaprogramming, so it is nevertheless endlessly
frustrating trying to get it to work correctly which is often a matter
of trying one trick or another.
This is just a way of saying that the shotgun approach in Boost PP of
having clang-cl act like VC++ is almost certainly wrong. And needless to
say neither I, and almost certainly neither Paul Mensonides, wants to
spend any time working with another C++ preprocessor "like", or
"similar", or "emulating" in certain respects but not all the VC++
preprocessor as far as Boost PP code is involved. But if some clang
developer and preprocessing guru would like to join the Boost PP team
and hack away at the code to get clang-cl to work in Boost PP in some
sort of VC++ emulation mode, please feel free to do so. But having
worked with the VC++ preprocessor in both Boost PP and my own VMD
library, I wouldn't wish such work on my worst enemy.
My suggestion to clang-cl developers working with the preprocessor
follows the thinking of Matt Calabrese in his post. If it is possible it
would be optimal if a #pragma could control the expansion of macros
between whatever is the VC++ emulation which clang-cl currentlty employs
and the conforming C++ preprocessor which clang is in its other builds.
I do not know how feasible this is but I hope it is so. In this way we
could surround the code in Boost PP when clang-cl is being used in such
a way that C++ standard preprocessing can be done while the VC++
emulation mode is used to compile the incorrect C++ preprocessor code in
VC11's xstddef and wherever such erroneous stuff occurs in other
Microsoft header files.
More information about the cfe-dev
mailing list