SQLite

Please post support and help requests here.
muellerto
Posts: 23
Joined: 13 May 2009, 18:06

SQLite

Postby muellerto » 13 May 2009, 18:24

I want to compile a simple SQLite database application on a 64bit-Linux using g++ 4.3.1 and the very new POCO 1.3.5, but I get a mysterious compilation error in Typehandler.h:

Code: Select all

/usr/local/include/Poco/Data/TypeHandler.h: In function "void Poco::Data::tupleExtract(size_t&, TupleType, DefValType, Poco::Data::AbstractExtractor*)":
/usr/local/include/Poco/Data/TypeHandler.h:181: error: type/value mismatch at argument 1 in template parameter list for "template<class _Key, class _Compare, class _Alloc> class std::set"
/usr/local/include/Poco/Data/TypeHandler.h:181: error:   expected a type, got "N"
/usr/local/include/Poco/Data/TypeHandler.h:181: error: template argument 2 is invalid
/usr/local/include/Poco/Data/TypeHandler.h:181: error: template argument 3 is invalid


I just included <Poco/Data/Session.h> in a .cc-file, I did nothing else. Is this a g++ related problem? Or do I need other headers or namespaces or defines before this include?

muellerto
Posts: 23
Joined: 13 May 2009, 18:06

Re: SQLite

Postby muellerto » 14 May 2009, 18:25

I solved it!

The original function in TypeHandler.h looks like this:

Code: Select all

template <typename TupleType, typename DefValType, typename Type, int N>
POCO_TUPLE_TYPE_HANDLER_INLINE
void tupleExtract(std::size_t& pos, TupleType tuple, DefValType defVal, AbstractExtractor* pExt)
{
   if (!pExt->extract(pos, tuple.template get<N>()))
         tuple.template set<N>(defVal.template get<N>());                // <-- set !
   pos += TypeHandler<Type>::size();
}

If g++ sees the word "set" he will indeed interpret it as "stl::set". So g++ gets confused about it's template arguments. As a human I can guess it shouldn't be interpreted as "stl::set" but as the set method from the class Tuple. I changed the function as follows, which solves the problem:

Code: Select all

template <typename TupleType, typename DefValType, typename Type, int N>
POCO_TUPLE_TYPE_HANDLER_INLINE
void tupleExtract(std::size_t& pos, TupleType tuple, DefValType defVal, AbstractExtractor* pExt)
{
   if (!pExt->extract(pos, tuple.template get<N>()))
         tuple.template TupleType::set<N>(defVal.template get<N>());     // <-- explain what set is really meant
   pos += TypeHandler<Type>::size();
}

It would be good if this change could be included in the next official distribution.

Further I guess the mysterious prefix "tuple.template" has been placed there to make clear what "set" should mean. But in my case it really didn't work and I even wonder that this is "ordinary" C++. Is this new? For g++ this means nothing and I can delete it without any loss of information. So I recommend to eliminate all these "tuple.template" things and to replace them by a well known, ordinary, readable and portable "TupleType::".

alex
Posts: 1246
Joined: 11 Jul 2006, 16:27
Location: United_States

Re: SQLite

Postby alex » 14 May 2009, 19:39

muellerto wrote:I solved it!

Thank you. A question, though: do you have

Code: Select all

using namespace std;
somewhere in your code? If so, try to remove it and see what happens. We'll fix this, but I'd like to know what exactly the root cause is
muellerto wrote:It would be good if this change could be included in the next official distribution.

If you would file a SF tracker item after you find out the answer to the above question, we'd appreciate it.
muellerto wrote:So I recommend to eliminate all these "tuple.template" things and to replace them by a well known, ordinary, readable and portable "TupleType::".

No. It is needed by some compilers. I do not rember off the top of my head whether it was an older version of gcc or MSVC, but 'template' must remain there. It is standard, hence portable.

muellerto
Posts: 23
Joined: 13 May 2009, 18:06

Re: SQLite

Postby muellerto » 14 May 2009, 20:11

Yeah, it's getting clearer and clearer now. (I just got the picture while I was showering ...) My case could only happen because I had indeed a "using namespace std;" before the #include of the POCO header. This was the entire problem. If I move my using-namespace-line below this #include everything works fine. (But this leads to a larger reorganization now in a lot of my files ...)

So, just mention not to have "using namespace std;" before POCO-includes somewhere in the documentation :)

alex
Posts: 1246
Joined: 11 Jul 2006, 16:27
Location: United_States

Re: SQLite

Postby alex » 14 May 2009, 20:20

muellerto wrote:So, just mention not to have "using namespace std;" before POCO-includes somewhere in the documentation :)


C++ Coding Style Guide wrote:Recommendation 59
Do not use using namespace. It causes excessive namespace pollution that may lead to subtle errors. Always be explicit and use non-namespace using. This is also valid for the std namespace. Do not use using namespace std;.


We do occasionally break this recommendation in controlled ways (such as, e.g. 'using namespace Poco::Data::Keywords') but it is a good practice to stick to it.

Edit (I knew it was somewhere):

C++ Coding Style Guide wrote:Rule 74
Do not place using namespace in a header file or before an #include.

muellerto
Posts: 23
Joined: 13 May 2009, 18:06

Re: SQLite

Postby muellerto » 15 May 2009, 08:44

I learned something. Until now I never had a case where "using namespace std;" caused such a problem.

But nevertheless I assume POCO has a problem there. If just a global symbol (especially a function template or a class template) named "set" or "get" is declared before this header include at least g++ will surely get confused about it. And if this symbol has a template parameter of <int N> it could even be wrongly compiled! Perhaps the problem is rather on the g++ side because of ignoring this "tuple.template" construct.

alex
Posts: 1246
Joined: 11 Jul 2006, 16:27
Location: United_States

Re: SQLite

Postby alex » 15 May 2009, 13:07

muellerto wrote:I learned something. Until now I never had a case where "using namespace std;" caused such a problem.

Well, if you think about it, by doing that you are effectively bringing the whole standard library into the global namespace. Namespaces have been introduced into the language for a reason and if you choose to ignore the reason, you are exposing yourself to the consequences.
muellerto wrote:But nevertheless I assume POCO has a problem there. If just a global symbol (especially a function template or a class template) named "set" or "get" is declared before this header include at least g++ will surely get confused about it. And if this symbol has a template parameter of <int N> it could even be wrongly compiled! Perhaps the problem is rather on the g++ side because of ignoring this "tuple.template" construct.

I dont think the danger is so real (although g++ has taken a course of annoyance recently) because, sooner or later, it would figure out that it can not make sense out of the '.template'.


Return to “Support”

Who is online

Users browsing this forum: No registered users and 1 guest