<html>
    <head>
      <base href="https://bugs.llvm.org/">
    </head>
    <body><table border="1" cellspacing="0" cellpadding="8">
        <tr>
          <th>Bug ID</th>
          <td><a class="bz_bug_link 
          bz_status_NEW "
   title="NEW - Preprocessor bug/incompatibility regarding __VA_ARGS__ and comma when compiling with -fms-compatibility on Windows"
   href="https://bugs.llvm.org/show_bug.cgi?id=43282">43282</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>Preprocessor bug/incompatibility regarding __VA_ARGS__ and comma when compiling with -fms-compatibility on Windows
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>new-bugs
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>trunk
          </td>
        </tr>

        <tr>
          <th>Hardware</th>
          <td>PC
          </td>
        </tr>

        <tr>
          <th>OS</th>
          <td>All
          </td>
        </tr>

        <tr>
          <th>Status</th>
          <td>NEW
          </td>
        </tr>

        <tr>
          <th>Severity</th>
          <td>normal
          </td>
        </tr>

        <tr>
          <th>Priority</th>
          <td>P
          </td>
        </tr>

        <tr>
          <th>Component</th>
          <td>new bugs
          </td>
        </tr>

        <tr>
          <th>Assignee</th>
          <td>unassignedbugs@nondot.org
          </td>
        </tr>

        <tr>
          <th>Reporter</th>
          <td>ToHe_EMA@gmx.de
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>htmldeveloper@gmail.com, llvm-bugs@lists.llvm.org
          </td>
        </tr></table>
      <p>
        <div>
        <pre>We are currently exploring to compile our software on Windows with Clang, but
hit a couple Clang/LLVM bugs along the way. This one is about incorrect
emulation of preprocessor.

Minimal code to reproduction the problem:
#define BUILD_LIB_XYZ ,
#define DLL(...) COMBINE(DLL_HELP_GET_THIRD_ARGUMENT(__VA_ARGS__, "dllexport",
"dllimport"))
#define DLL_HELP_GET_THIRD_ARGUMENT(A, B, C, ...) C
#define COMBINE(...) __VA_ARGS__
static_assert(0, DLL(BUILD_LIB_XYZ));

The code should output "dllexport" because DLL() gets a comma inside the
__VA_ARGS__ which shifts the "dllexport" from the second to the third argument.
However on Clang with -fms-compatibility this is not the case, and "dllimport"
is printed instead. Note that only on Microsoft's compiler the COMBINE is
necessary to get this correct behavour.

Background: In our software project we use this preprocessor trick to choose
between __declspec(dllimport) and __declspec(dllexport) (or actually
__attribute__((dllexport)) and __attribute__((dllimport)) on Clang). It works
like this: In the build system we define a preprocessor symbol like
BUILD_LIB_XYZ=, only when building library XYZ. This automatically evaluates to
DLLEXPORT for all the API of library XYZ and DLLIMPORT for everything else
without having to setup new macros for each library. It worked fine on
Microsoft's Compiler since at least 2015, GCC and even Clang, normally at
least. However not when provided with -fms-compatibility. We cannot disable
that option either though because our source files sometimes use <Windows.h>
for platformspecific API and as far as we know, there is no way to only
selectively apply -fms-compatibility for certain #includes.

Live code on Godbolt: <a href="https://gcc.godbolt.org/z/KODv16">https://gcc.godbolt.org/z/KODv16</a></pre>
        </div>
      </p>


      <hr>
      <span>You are receiving this mail because:</span>

      <ul>
          <li>You are on the CC list for the bug.</li>
      </ul>
    </body>
</html>