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

Make U macro less problematic #1214

Open
nickaein opened this issue Jul 31, 2019 · 2 comments
Open

Make U macro less problematic #1214

nickaein opened this issue Jul 31, 2019 · 2 comments

Comments

@nickaein
Copy link

I was getting compiler errors on ranges-v3 library when I included headers of this library. After wasting hours and almost giving up on this library, I found out that U macro is causing the issue and I can disable it by _TURN_OFF_PLATFORM_STRING macro.

Since this has caused several issues (#812, #473, #435), we can take some actions to mitigate future problems:

1. Make the documentation more visible

The current documentation on this macro is obscure. I even skimmed through FAQ but didn't notice it at the end of paragraph:

If you are using a library causing conflicts with the 'U' macro, for example Boost.Iostreams it can be turned off by defining the macro '_TURN_OFF_PLATFORM_STRING' before including the C++ REST SDK header files.

Mentioning this macro in homepage or usage section can increase its visibility and prevent possible mistakes.

2. Rename it. Having it is undefined behavior

Based on C++ Standard, identifiers with an underscore followed by an uppercase letter are reserved and defining them would be undefined behavior. Having this is not a good practice in such a well-known library.

3. Deprecate and eventually remove U

We can deprecate U and replace it with a more sensible macro definition. For keeping backward compatibility, we can have another macro (off by default) that when defined it brings back U for the users that heavily depends on it.


As reference (and helping the search engines), here is the compile errors I was getting:

ranges v-3: 0.4.0-1

Scanning dependencies of target nazdikpt
[  7%] Building CXX object CMakeFiles/nazdikpt.dir/src/server-db-logging.cpp.o
[  7%] Building CXX object CMakeFiles/nazdikpt.dir/src/application.cpp.o
[ 14%] Building CXX object CMakeFiles/nazdikpt.dir/src/server-http.cpp.o
[ 14%] Building CXX object CMakeFiles/nazdikpt.dir/src/server.cpp.o
In file included from /usr/include/range/v3/utility/concepts.hpp:26,
                 from /usr/include/range/v3/utility/copy.hpp:18,
                 from /usr/include/range/v3/begin_end.hpp:23,
                 from /usr/include/range/v3/core.hpp:17,
                 from /usr/include/range/v3/all.hpp:17,
                 from /home/isaac/balad-pt/include/map_matching.hpp:23,
                 from /home/isaac/balad-pt/include/bus_model.h:8,
                 from /home/isaac/balad-pt/include/transport_system.h:15,
                 from /home/isaac/balad-pt/include/application.h:3,
                 from /home/isaac/balad-pt/include/server.h:4,
                 from /home/isaac/balad-pt/src/server-db-logging.cpp:1:
/usr/include/range/v3/utility/swap.hpp:132:55: error: lambda-expression in template-argument
                     !is_adl_swappable_<T (&)[N], U (&)[N]>::value &&
                                                       ^
/usr/include/range/v3/utility/swap.hpp:132:56: error: capture of non-variable ‘N’
                     !is_adl_swappable_<T (&)[N], U (&)[N]>::value &&
                                                        ^
/usr/include/range/v3/utility/swap.hpp:129:50: note: ‘long unsigned int N’ declared here
                 template<typename T, typename U, std::size_t N>
                                                  ^~~
/usr/include/range/v3/utility/swap.hpp:132:58: error: template argument 2 is invalid
                     !is_adl_swappable_<T (&)[N], U (&)[N]>::value &&
                                                          ^
In file included from /usr/include/cpprest/asyncrt_utils.h:16,
                 from /usr/include/cpprest/http_msg.h:15,
                 from /usr/include/cpprest/http_listener.h:16,
                 from /home/isaac/balad-pt/include/server-http.h:7,
                 from /home/isaac/balad-pt/include/server.h:3,
                 from /home/isaac/balad-pt/src/server-db-logging.cpp:1:
/usr/include/range/v3/utility/swap.hpp:134:39: error: expected identifier before ‘&’ token
                 operator()(T (&t)[N], U (&u)[N]) const
                                       ^
In file included from /usr/include/range/v3/utility/concepts.hpp:26,
                 from /usr/include/range/v3/utility/copy.hpp:18,
                 from /usr/include/range/v3/begin_end.hpp:23,
                 from /usr/include/range/v3/core.hpp:17,
                 from /usr/include/range/v3/all.hpp:17,
                 from /home/isaac/balad-pt/include/map_matching.hpp:23,
                 from /home/isaac/balad-pt/include/bus_model.h:8,
                 from /home/isaac/balad-pt/include/transport_system.h:15,
                 from /home/isaac/balad-pt/include/application.h:3,
                 from /home/isaac/balad-pt/include/server.h:4,
                 from /home/isaac/balad-pt/src/server-db-logging.cpp:1:
/usr/include/range/v3/utility/swap.hpp:134:47: error: declaration of ‘u’ as array of references
                 operator()(T (&t)[N], U (&u)[N]) const
                                               ^
In file included from /usr/include/range/v3/utility/concepts.hpp:26,
                 from /usr/include/range/v3/utility/copy.hpp:18,
                 from /usr/include/range/v3/begin_end.hpp:23,
                 from /usr/include/range/v3/core.hpp:17,
                 from /usr/include/range/v3/all.hpp:17,
                 from /home/isaac/balad-pt/include/map_matching.hpp:23,
                 from /home/isaac/balad-pt/include/bus_model.h:8,
                 from /home/isaac/balad-pt/include/transport_system.h:15,
                 from /home/isaac/balad-pt/include/application.h:3,
                 from /home/isaac/balad-pt/include/server.h:4,
                 from /home/isaac/balad-pt/src/server.cpp:1:
/usr/include/range/v3/utility/swap.hpp:132:55: error: lambda-expression in template-argument
                     !is_adl_swappable_<T (&)[N], U (&)[N]>::value &&
                                                       ^
/usr/include/range/v3/utility/swap.hpp:132:56: error: capture of non-variable ‘N’
                     !is_adl_swappable_<T (&)[N], U (&)[N]>::value &&
                                                        ^
/usr/include/range/v3/utility/swap.hpp:129:50: note: ‘long unsigned int N’ declared here
                 template<typename T, typename U, std::size_t N>
                                                  ^~~
/usr/include/range/v3/utility/swap.hpp:132:58: error: template argument 2 is invalid
                     !is_adl_swappable_<T (&)[N], U (&)[N]>::value &&
                                                          ^
In file included from /usr/include/cpprest/asyncrt_utils.h:16,
                 from /usr/include/cpprest/http_msg.h:15,
                 from /usr/include/cpprest/http_listener.h:16,
                 from /home/isaac/balad-pt/include/server-http.h:7,
                 from /home/isaac/balad-pt/include/server.h:3,
                 from /home/isaac/balad-pt/src/server.cpp:1:
/usr/include/range/v3/utility/swap.hpp:134:39: error: expected identifier before ‘&’ token
                 operator()(T (&t)[N], U (&u)[N]) const
                                       ^
In file included from /usr/include/range/v3/utility/concepts.hpp:26,
                 from /usr/include/range/v3/utility/copy.hpp:18,
                 from /usr/include/range/v3/begin_end.hpp:23,
                 from /usr/include/range/v3/core.hpp:17,
                 from /usr/include/range/v3/all.hpp:17,
                 from /home/isaac/balad-pt/include/map_matching.hpp:23,
                 from /home/isaac/balad-pt/include/bus_model.h:8,
                 from /home/isaac/balad-pt/include/transport_system.h:15,
                 from /home/isaac/balad-pt/include/application.h:3,
                 from /home/isaac/balad-pt/include/server.h:4,
                 from /home/isaac/balad-pt/src/server.cpp:1:
/usr/include/range/v3/utility/swap.hpp:134:47: error: declaration of ‘u’ as array of references
                 operator()(T (&t)[N], U (&u)[N]) const
                                               ^
/usr/include/range/v3/utility/swap.hpp: In member function ‘constexpr meta::v1::if_c<(<expression error> && ranges::v3::is_swappable_with<T&, U&>::value)> ranges::v3::adl_swap_detail::swap_fn::operator()(...) const’:
/usr/include/range/v3/utility/swap.hpp:138:33: error: ‘t’ was not declared in this scope
                         (*this)(t[i], u[i]);
                                 ^
/usr/include/range/v3/utility/swap.hpp: In member function ‘constexpr meta::v1::if_c<(<expression error> && ranges::v3::is_swappable_with<T&, U&>::value)> ranges::v3::adl_swap_detail::swap_fn::operator()(...) const’:
/usr/include/range/v3/utility/swap.hpp:138:33: error: ‘t’ was not declared in this scope
                         (*this)(t[i], u[i]);
                                 ^
/usr/include/range/v3/utility/swap.hpp:138:39: error: ‘u’ was not declared in this scope
                         (*this)(t[i], u[i]);
                                       ^
/usr/include/range/v3/utility/swap.hpp:138:39: error: ‘u’ was not declared in this scope
                         (*this)(t[i], u[i]);
                                       ^
In file included from /usr/include/cpprest/asyncrt_utils.h:16,
                 from /usr/include/cpprest/http_msg.h:15,
                 from /usr/include/cpprest/http_listener.h:16,
                 from /home/isaac/balad-pt/include/server-http.h:7,
                 from /home/isaac/balad-pt/include/server.h:3,
                 from /home/isaac/balad-pt/src/server.cpp:1:
/usr/include/range/v3/detail/variant.hpp: In member function ‘void ranges::v3::detail::construct_fn<N, Ts>::construct_(U&, meta::v1::index_sequence<Is ...>)’:
/usr/include/range/v3/detail/variant.hpp:380:53: error: expected type-specifier before ‘static_cast’
                     ::new((void*)std::addressof(u)) U(static_cast<Ts&&>(std::get<Is>(args_))...);
                                                     ^
In file included from /usr/include/cpprest/asyncrt_utils.h:16,
                 from /usr/include/cpprest/http_msg.h:15,
                 from /usr/include/cpprest/http_listener.h:16,
                 from /home/isaac/balad-pt/include/server-http.h:7,
                 from /home/isaac/balad-pt/include/server.h:3,
                 from /home/isaac/balad-pt/src/server-db-logging.cpp:1:
/usr/include/range/v3/detail/variant.hpp: In member function ‘void ranges::v3::detail::construct_fn<N, Ts>::construct_(U&, meta::v1::index_sequence<Is ...>)’:
/usr/include/range/v3/detail/variant.hpp:380:53: error: expected type-specifier before ‘static_cast’
                     ::new((void*)std::addressof(u)) U(static_cast<Ts&&>(std::get<Is>(args_))...);
                                                     ^
make[2]: *** [CMakeFiles/nazdikpt.dir/build.make:297: CMakeFiles/nazdikpt.dir/src/server-db-logging.cpp.o] Error 1
make[2]: *** Waiting for unfinished jobs....
make[2]: *** [CMakeFiles/nazdikpt.dir/build.make:323: CMakeFiles/nazdikpt.dir/src/server.cpp.o] Error 1
make[1]: *** [CMakeFiles/Makefile2:73: CMakeFiles/nazdikpt.dir/all] Error 2
make: *** [Makefile:84: all] Error 2
@nickaein nickaein changed the title Make U macro less problametic Make U macro less problematic Jul 31, 2019
@elfring
Copy link

elfring commented Aug 2, 2019

See also a previous bug report.

@david-antiteum
Copy link

So far, the solution in my code is:

#undef U

and, instead of U("something"), I will do utility::conversions::to_string_t("something")

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

No branches or pull requests

3 participants