Reputation: 25927
I'm converting my legacy VC++ project to be compatible with Android NDK and I'm getting a weird error. The message says:
[armeabi] Compile++ thumb: procalc-core <= pcc_arithmetics.cpp
In file included from D:/Dokumenty/Dev/Android/ProCalc//jni/pcc_arithmetics.h:10:0,
from D:/Dokumenty/Dev/Android/ProCalc//jni/pcc_arithmetics.cpp:1:
D:/Dokumenty/Dev/Android/ProCalc//jni/pcc_common.h: In static member function
'static std::string ProCalcCore::CommonTools::ToStringBase(T, int)':
D:/Dokumenty/Dev/Android/ProCalc//jni/pcc_common.h:102:68: error: there are no
arguments to 'ConvertException' that depend on a template parameter, so a
declaration of 'ConvertException' must be available [-fpermissive]
throw ConvertException(PROCALC_ERROR_SYNTAX_INVALID_INTEGER_BASE);
^
D:/Dokumenty/Dev/Android/ProCalc//jni/pcc_common.h:102:68: note: (if you use
'-fpermissive', G++ will accept your code, but allowing the use of an undeclared
name is deprecated)
make.exe: *** [D:/Dokumenty/Dev/Android/ProCalc//obj/local/armeabi/objs/procalc-
core/pcc_arithmetics.o] Error 1
The error is thrown in the following place:
template <typename T>
std::string CommonTools::ToStringBase(T val, int base)
{
if (base < 2)
throw ConvertException(PROCALC_ERROR_SYNTAX_INVALID_INTEGER_BASE);
The caps-named error value is a #define
d int value.
ConvertException
is declared in another file:
namespace ProCalcCore
{
(...)
class ConvertException : public InternalException
{
public:
ConvertException(const unsigned long int & newErrorCode);
};
When I try to change ConvertException
to ProCalcCore::ConvertException
, I get another error:
D:/Dokumenty/Dev/Android/ProCalc//jni/pcc_common.h:102:10: error: 'ConvertException'
is not a member of 'ProCalcCore'
All dependencies are resolved correctly - in VS the project compiles without problems.
How can I solve it? What causes this error?
Upvotes: 0
Views: 253
Reputation: 275730
"In visual studio the project compiles without problems" is weak evidence that your dependencies are correct.
The problem is that ConvertException
is not visible at the point where the template
is declared. Some versions of Visual Studio only try to bind such "free" types and expressions at the point where the template
is instantiated, which is not correct under the C++ standard.
So your compiler is pointing out that it cannot work out what type ConvertException
refers to. In order for it to know what type it refers to, you need to either forward declare it (which can have its own problems), or #include
the header file prior to using it.
If you think you are already #include
ing it, often your problem is that the header file that contains ConvertException
ends up #include
ing CommonTools::ToStringBase
. The header file guards (or #pragma once
) then eliminate the infinite loop.
Annoyingly, how the infinite loop is eliminated depends on which header file you include first! If you include the ConvertException
header file, it then includes ToStringBase
, which includes ConvertException
back. That second #include "ConvertException.h"
is eliminated by header-file #define
guards.
If you instead included ToStringBase
first, it would include ConvertException
, which then includes ToStringBase
, which is eliminated by the header guards.
So whatever header file is included first ends up being parsed second.
Upvotes: 1