out-of-line declaration of - template inline functions

Hi,

I am getting the 'out-of-line declaration of' compiler error when trying to complie some libraries. I am wondering what causes this. The error appers when encountering these inline fucntion declartion in the header file:

namespace std{
template<class T>
inline Libs::class1<T> std::sqrt(const Libs::class1<T> & z);
}

The error in this case is:
out-of-line declaration of 'sqrt' does not match any declaration in namespace 'std'

I am trying to complie it on a mac (Mojave)!

Is this uncompilable? Is it possible to force through the compilation and ignore the errors?

Thanks!
That's something you don't see every day.

First off, it's undefined behavior to add stuff to namespace std (outside of a few very narrow circumstances, like specializing certain templates). That doesn't mean the compiler should reject it, it means the compiler should feel free to do whatever with it. The library you're using is doing something very naughty by trying to add their own sqrt overload, even if it doesn't seem like it. In fact, the fact that it's undefined behavior is the reason why you're having trouble but the library authors were not. We'll get to why that is in a second.

Anyway, the problem has to do with that std:: prefix. By having it, you're essentially making the declaration an out-of-line declaration, whereby your compiler expects to find an existing declaration inside of namespace std. There isn't one, of course, hence the error.

You can replicate this error with namespaces other than std:
1
2
3
namespace ans {
	int ans::foo(int z);
}
error: out-of-line declaration of 'foo' does not match any declaration in namespace 'ans'


It's fairly simple to fix in this example: just delete the ans:: part.

Is it possible to force through the compilation and ignore the errors?
The answer to this part of your question is always "no, and even if it were you shouldn't". Errors like these are not warnings: they're not your compiler saying "something is probably wrong here so I'm stopping compilation", they're saying "this code is not valid and must be fixed".

That said, the provided code will compile using g++, but not with clang++ (which macOS uses a fork of in Xcode). Apparently g++ doesn't mind out-of-line declarations of certain std::sqrt function templates as much as clang++ does. As far as I can tell, both behaviors are technically legal. Presumably, whoever wrote your library was using g++ (or another compiler that does the same) and thought it was acceptable because the compiler allowed it.

-Albatross
Hi,

Thanks, changing to g++ did indeed help and the error is gone now. It was not too clear to which compiler I am actually using since there is a gcc in /usr/bin/ but that turns out to be clang++ as well. In any case now I have to chase some make errors:

make[3]: *** [mpi_config.lo] Error 1
make[2]: *** [all-recursive] Error 1
make[1]: *** [all] Error 2
make: *** [all-recursive] Error 1

But I guess these will be "easier"! :D

Thanks again!
Solo
Topic archived. No new replies allowed.