scipy: BUG: Macro collision (`complex`) with Windows SDK in amos code

While building 1.13.0rc1 in conda-forge, I’m running into macro collisions with the windows SDK:

[64/1477] Compiling C object scipy/special/lib_amos.a.p/_amos.c.obj
FAILED: scipy/special/lib_amos.a.p/_amos.c.obj 
"clang-cl" "-Iscipy\special\lib_amos.a.p" "-Iscipy\special" "-I..\scipy\special" "-Iscipy\_lib" "-I..\scipy\_lib" "-I..\scipy\_build_utils\src" "-DNDEBUG" "/MD" "/nologo" "/showIncludes" "/utf-8" "/W2" "/clang:-std=c99" "/O2" "-Wno-unused-but-set-variable" "-Wno-unused-function" "-Wno-conversion" "-Wno-misleading-indentation" "-D_USE_MATH_DEFINES" "/Fdscipy\special\lib_amos.a.p\_amos.c.pdb" /Foscipy/special/lib_amos.a.p/_amos.c.obj "/c" ../scipy/special/_amos.c
In file included from ../scipy/special/_amos.c:96:
../scipy/special\_amos.h(106,15): error: expected ';' after top level declarator
  106 | double complex amos_airy(double complex, int, int, int *, int *);
      |               ^
      |               ;
../scipy/special\_amos.h(107,61): error: redefinition of parameter '_complex'
  107 | int amos_besh(double complex, double, int, int, int, double complex *, int *);
      |                                                             ^
C:\Program Files (x86)\Windows Kits\10\include\10.0.22621.0\ucrt\corecrt_math.h(44,29): note: expanded from macro 'complex'
   44 |             #define complex _complex
      |                             ^

I’m not sure if this would be solved by WIN32_LEAN_AND_MEAN, but in any case, looking at corecrt_math.h directly, the code shows that we could disable it by setting _COMPLEX_DEFINED (or investigating how _CRT_INTERNAL_NONSTDC_NAMES can be disabled).

    // Definition of the _complex struct to be used by those who use the complex
    // functions and want type checking.
    #ifndef _COMPLEX_DEFINED
        #define _COMPLEX_DEFINED

        struct _complex
        {
            double x, y; // real and imaginary parts
        };

        #if defined(_CRT_INTERNAL_NONSTDC_NAMES) && _CRT_INTERNAL_NONSTDC_NAMES && !defined __cplusplus
            // Non-ANSI name for compatibility
            #define complex _complex
        #endif
    #endif

PS. This is ultimately a consequence of https://github.com/scipy/scipy/pull/19587, so CC @ilayn

About this issue

  • Original URL
  • State: open
  • Created 3 months ago
  • Comments: 21 (21 by maintainers)

Most upvoted comments

@tylerjereddy, I’ve reviewed and merged @izaid’s fix. Things should be good now.

I doubt it needs to be done today, I still have to build new OpenBLAS binaries off their develop branch when Matti sends me instructions. Keeping me posted if it gets blocked by something unanticipated would be good though.

See this for the full story of using complex numbers in C/C++ in a portable way: https://github.com/lysnikolaou/c-cpp-complex. (Cc @lysnikolaou for visibility)

tl;dr it’s very complex

Then can I leave it to you folks? I’m a bit running out of steam with special code.

Yes. I’ll do it today.

I think this is not a macro collision but clang thinks double complex is a function called complex with output type double. Or something like that.

I mean…

Anyways, if we can find what clang-cl thinks how double complex data type should be defined then we should be able to fix it probably.