One of these issues of nlohmann/json opensource library drew my attention.
I have a minimal reproduction of the case that does not compile under few version of desktop gcc (4.8, 4.9, also tried 5+) but compiles well with mac clang and Android ndk's gcc 4.9
#include <limits>
struct base {
virtual void foo() = 0;
};
int main() {
(void)numeric_limits<base>::is_signed;
}
std::numeric_limits
/usr/include/c++/4.8/limits: In instantiation of 'struct std::numeric_limits<base>': main.cpp:11:94: required from here
/usr/include/c++/4.8/limits:309:7: error: cannot allocate an object of abstract type 'base'
min() _GLIBCXX_USE_NOEXCEPT { return _Tp(); }
std::is_abstract
template <typename T>
struct foo
{
static T bar();
static constexpr bool value = true;
};
struct abstract
{
virtual ~abstract() = 0;
};
int main()
{
(void) foo<abstract>::value;
}
foo<abstract>::bar
No, it is not a bug. It is just a bad test.
The only difference between GCC
and clang
in this case is the way they process template class functions:
GCC
: All of them in once.clang
: Only the one that has been used.In our first example, the function min()
doesn't get called, and therefore, clang
doesn't has a problem with it. GCC
, parses all the functions and find out that min()
is invalid.
In the second example, the same happens: bar()
doesn't get called by anyone and therefore clang
is OK about it being ill-formed. But again, GCC
, have a problem with it, although hasn't been used anywhere in the program.
Saying that something is bad is not enough, let's fix it: this example would fail with both GCC
and clang
with almost the same error (invalid abstract return type ‘base’
or allocating an object of abstract class type 'base'
).
#include <limits>
struct base {
virtual void foo() = 0;
};
int main() {
(void)std::numeric_limits<base>::min();
}