Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create a compiler flag to disable the definition of I #191

Closed
phillipjohnston opened this issue Jan 16, 2019 · 7 comments · Fixed by #209
Closed

Create a compiler flag to disable the definition of I #191

phillipjohnston opened this issue Jan 16, 2019 · 7 comments · Fixed by #209

Comments

@phillipjohnston
Copy link
Contributor

phillipjohnston commented Jan 16, 2019

When using this library with C++, there are apparently conflicts with some of the template functions. People are using "I" in C++ headers, which gets substituted with the _Complex_I macro. (It's truly a great mystery as to why the particular headers I'm using even include cmath, but I'll leave that for another project).

The easiest solution that I can think would be to have a compile-time switch that could disable the definition of I. In my initial sanity check, everything seems to compile/link fine - I build openlibm with I defined, and then remove the definition for my C++ project's build.

Before I head further down that route (with a potential PR), I wanted to know whether you foresee any difficulties arising from using this library in C++ with I undefined (or if you'd accept such a change at all).

@phillipjohnston
Copy link
Contributor Author

Here are some example compiler errors for reference:

In file included from ../src/stdlibs/GSL/include/gsl/gsl:20:
In file included from ../src/stdlibs/GSL/include/gsl/gsl_algorithm:21:
In file included from ../src/stdlibs/GSL/include/gsl/span:21:
../src/stdlibs/GSL/include/gsl/gsl_byte:189:15: error: expected ',' or '>' in template-parameter-list
template <int I>
              ^
../src/stdlibs/libc/openlibm/include/openlibm_complex.h:28:11: note: expanded from macro 'I'
#define I _Complex_I
          ^
../src/stdlibs/libc/openlibm/include/openlibm_complex.h:27:20: note: expanded from macro '_Complex_I'
#define _Complex_I 1.0fi

And:

In file included from ../src/stdlibs/GSL/include/gsl/gsl:20:
In file included from ../src/stdlibs/GSL/include/gsl/gsl_algorithm:21:
In file included from ../src/stdlibs/GSL/include/gsl/span:21:
../src/stdlibs/GSL/include/gsl/gsl_byte:192:21: error: invalid operands to binary expression ('_Complex float' and '_Complex float')
    static_assert(I >= 0 && I <= 255,
                  ~ ^  ~
../src/stdlibs/GSL/include/gsl/gsl_byte:192:31: error: invalid operands to binary expression ('_Complex float' and '_Complex float')
    static_assert(I >= 0 && I <= 255,
                            ~ ^  ~~~
../src/stdlibs/GSL/include/gsl/gsl_byte:194:12: error: static_cast from '_Complex float' to 'std::byte' is not allowed
    return static_cast<byte>(I);
           ^~~~~~~~~~~~~~~~~~~~
../src/stdlibs/GSL/include/gsl/gsl_byte:190:16: error: no return statement in constexpr function
constexpr byte to_byte() noexcept

@phillipjohnston phillipjohnston changed the title Create a compiler-time flag to disable the definition of I Create a compiler flag to disable the definition of I Jan 16, 2019
@ViralBShah
Copy link
Member

Thanks for checking. I am not inclined to accept this since it feels a bit strange. Maybe there are other workarounds?

@yuyichao
Copy link
Contributor

That def should probably be disabled for c++.

@yuyichao
Copy link
Contributor

And while the standard says it can be undef by the program, including it in math.h without complex.h is likely problematic.

@phillipjohnston
Copy link
Contributor Author

I did not notice that it was being included in math.h by default. That could very well be the source of the trouble.

#undef doesn't serve as a workaround in the case of the C++ STL, since that requires modifying STL source code.

The other option for a workaround is to have my math.h file include openlibm_fenv.h and openlibm_math.h instead of openlibm.h. Then complex.h can include openlibm_complex.h. Worth documenting somewhere, I think.

@phillipjohnston
Copy link
Contributor Author

This approach did resolve the issue with the STL:

The other option for a workaround is to have my math.h file include openlibm_fenv.h and openlibm_math.h instead of openlibm.h. Then complex.h can include openlibm_complex.h. Worth documenting somewhere, I think.

@phillipjohnston
Copy link
Contributor Author

The stars have re-aligned and this is failing for me once again when compiling libcpp with openlibm.

This appears to be tied to x86_64 specifically. The reason is that openlibm_fenv.h includes "math_private.h", which exposes openlibm_complex.h. Nominally this is to have a definition of OLM_DLLEXPORT:

#undef OLM_DLLEXPORT
#ifdef _WIN32
# ifdef IMPORT_EXPORTS
#  define OLM_DLLEXPORT __declspec(dllimport)
# else
#  define OLM_DLLEXPORT __declspec(dllexport)
# endif
#else
#define OLM_DLLEXPORT __attribute__ ((visibility("default")))
#endif

This is defined originally in openlibm_math.h using the same values:

#ifdef _WIN32
# ifdef IMPORT_EXPORTS
#  define OLM_DLLEXPORT __declspec(dllimport)
# else
#  define OLM_DLLEXPORT __declspec(dllexport)
# endif
#else
#define OLM_DLLEXPORT __attribute__ ((visibility("default")))
#endif

Testing locally, I can resolve the compilation error if I replace the math_include.h header with the OLM_DLLEXPORT definition. The library builds successfully.

I will submit a PR that eliminates the macro duplication and decouples the openlibm_fenv_amd64.h header from math_private.h.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants