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

Fixes and workarounds for older gcc compilers #277

Merged

Conversation

kingsley-cheung
Copy link
Contributor

I saw compilation issues when using FakeIt with a legacy project that needs gcc 4.8.5.

A problem with an ambiguous call to std::abs(double):
g++ -flto -D__GXX_EXPERIMENTAL_CXX0X__ -I"../include" -I"../config/standalone" -O0 -g3 -Wall -Wextra -Wno-ignored-qualifiers -c -fmessage-length=0 -std=c++11 -MMD -MP -MF"argument_matching_tests.d" -MT"argument_matching_tests.d" -o "argument_matching_tests.o" "../tests/argument_matching_tests.cpp" In file included from ../include/fakeit/invocation_matchers.hpp:21:0, from ../include/fakeit/RecordedMethodBody.hpp:18, from ../include/fakeit/StubbingImpl.hpp:15, from ../include/fakeit/MockImpl.hpp:17, from ../include/fakeit/Mock.hpp:11, from ../include/fakeit/fakeit_root.hpp:3, from ../config/standalone/fakeit.hpp:4, from ../tests/argument_matching_tests.cpp:11: ../include/fakeit/argument_matchers.hpp: In instantiation of ‘bool fakeit::internal::ApproxEqCreator<ExpectedTRef, ExpectedMarginTRef>::createMatcher() const::Matcher::matches(const ActualT&) const [with ActualT = double; ExpectedTRef = int&&; ExpectedMarginTRef = double&&]’: ../include/fakeit/argument_matchers.hpp:476:17: required from ‘fakeit::TypedMatcher<ActualT>* fakeit::internal::ApproxEqCreator<ExpectedTRef, ExpectedMarginTRef>::createMatcher() const [with ActualT = double; ExpectedTRef = int&&; ExpectedMarginTRef = double&&]’ ../include/fakeit/MatchersCollector.hpp:57:104: required from ‘typename std::enable_if<typename fakeit::naked_type<A>::type::IsTypeCompatible<typename fakeit::naked_type<typename std::tuple_element<index, std::tuple<_Elements ...> >::type>::type>::value, void>::type fakeit::MatchersCollector<index, arglist>::CollectMatchers(Head&&) [with Head = fakeit::internal::ApproxEqCreator<int&&, double&&>; unsigned int index = 0u; arglist = {double}; typename std::enable_if<typename fakeit::naked_type<A>::type::IsTypeCompatible<typename fakeit::naked_type<typename std::tuple_element<index, std::tuple<_Elements ...> >::type>::type>::value, void>::type = void]’ ../include/fakeit/MethodMockingContext.hpp:260:13: required from ‘typename std::enable_if<(sizeof (matcherCreators ...) == sizeof (arglist ...)), void>::type fakeit::MethodMockingContext<R, arglist>::setMatchingCriteria(matcherCreators&& ...) [with matcherCreators = {fakeit::internal::ApproxEqCreator<int&&, double&&>}; R = int; arglist = {double}; typename std::enable_if<(sizeof (matcherCreators ...) == sizeof (arglist ...)), void>::type = void]’ ../include/fakeit/MethodMockingContext.hpp:302:112: required from ‘fakeit::MockingContext<R, arglist>& fakeit::MockingContext<R, arglist>::Using(arg_matcher&& ...) [with arg_matcher = {fakeit::internal::ApproxEqCreator<int&&, double&&>}; R = int; arglist = {double}]’ ../tests/argument_matching_tests.cpp:301:3: required from here ../include/fakeit/argument_matchers.hpp:474:65: error: call of overloaded ‘abs(double)’ is ambiguous return std::abs(actual - this->_expected) <= this->_expectedMargin;

There was also a problem with list-initialization used in constructor member initializer lists:
g++ -flto -D__GXX_EXPERIMENTAL_CXX0X__ -I"../include" -I"../config/standalone" -O0 -g3 -Wall -Wextra -Wno-ignored-qualifiers -c -fmessage-length=0 -std=c++11 -MMD -MP -MF"stubbing_tests.d" -MT"stubbing_tests.d" -o "stubbing_tests.o" "../tests/stubbing_tests.cpp" In file included from ../include/fakeit/StubbingImpl.hpp:16:0, from ../include/fakeit/MockImpl.hpp:17, from ../include/fakeit/Mock.hpp:11, from ../include/fakeit/fakeit_root.hpp:3, from ../config/standalone/fakeit.hpp:4, from ../tests/stubbing_tests.cpp:13: ../include/fakeit/StubbingProgress.hpp: In instantiation of ‘fakeit::helper::ArgValue<T, N>::ArgValue(T&&) [with T = std::vector<std::basic_string<char> >&; int N = 2]’: ../include/fakeit/StubbingProgress.hpp:493:49: required from ‘fakeit::helper::ArgValue<ArgType, std::is_placeholder<_Tp>::value> fakeit::placeholders::operator<=(PlaceHolder, ArgType&&) [with PlaceHolder = std::_Placeholder<2>; ArgType = std::vector<std::basic_string<char> >&; typename std::enable_if<static_cast<bool>(std::is_placeholder<_Tp>::value), bool>::type <anonymous> = 1u]’ ../tests/stubbing_tests.cpp:203:65: required from here ../include/fakeit/StubbingProgress.hpp:365:57: error: invalid initialization of non-const reference of type ‘std::vector<std::basic_string<char> >&’ from an rvalue of type ‘<brace-enclosed initializer list>’ ArgValue(T &&v): value { std::forward<T>(v) } {} ^ ../include/fakeit/StubbingProgress.hpp: In instantiation of ‘fakeit::helper::ArgValue<T, N>::ArgValue(T&&) [with T = std::vector<std::basic_string<char> >&; int N = 1]’: ../include/fakeit/StubbingProgress.hpp:493:49: required from ‘fakeit::helper::ArgValue<ArgType, std::is_placeholder<_Tp>::value> fakeit::placeholders::operator<=(PlaceHolder, ArgType&&) [with PlaceHolder = std::_Placeholder<1>; ArgType = std::vector<std::basic_string<char> >&; typename std::enable_if<static_cast<bool>(std::is_placeholder<_Tp>::value), bool>::type <anonymous> = 1u]’ ../tests/stubbing_tests.cpp:213:65: required from here ../include/fakeit/StubbingProgress.hpp:365:57: error: invalid initialization of non-const reference of type ‘std::vector<std::basic_string<char> >&’ from an rvalue of type ‘<brace-enclosed initializer list>’ make: *** [stubbing_tests.o] Error 1

Unit tests pass with GCC 4.8.5 and 7.5.0 with these minor changes.

@kingsley-cheung
Copy link
Contributor Author

I have also added a check to see if __has_include is defined as suggested in by gnu documentation. Again this is another problem with older compilers.

From what I understand __has_include is a C++17 feature so we need to support older compilers without it since FakeIt is targeted at C++11.

@coveralls
Copy link

Coverage Status

Coverage remained the same at 99.925% when pulling f7de082 on kingsley-cheung:fixes-for-older-gcc-compilers into ded6e47 on eranpeer:master.

@FranckRJ FranckRJ changed the base branch from master to dev-2.3.0 June 7, 2022 14:39
@FranckRJ FranckRJ added this to the 2.3.0 milestone Jun 7, 2022
@FranckRJ
Copy link
Collaborator

FranckRJ commented Jun 7, 2022

Thanks for the fixes, but just so you know, the compatibility with older compiler (non C++11-compliant compilers) is done as a best effort and won't really by checked by the CI, so in future updates some changes can make FakeIt incompatible again.

@FranckRJ FranckRJ merged commit 347baae into eranpeer:dev-2.3.0 Jun 7, 2022
@kingsley-cheung
Copy link
Contributor Author

Thanks for the fixes, but just so you know, the compatibility with older compiler (non C++11-compliant compilers) is done as a best effort and won't really by checked by the CI, so in future updates some changes can make FakeIt incompatible again.

@FranckRJ No problems. Understood regarding the best effort approach, so I will bear that in mind going forward. And thanks for your work on making Fakeit available.

@kingsley-cheung kingsley-cheung deleted the fixes-for-older-gcc-compilers branch June 8, 2022 02:33
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 this pull request may close these issues.

3 participants