[g++] Getting an error while using reinterpret_cast operator
Hi there!
I use g++ compiler which is built-in in Code::Blocks 10.05 and I have quite strange problem while using reinterpret_cast operator.
I'd like to convert following expression:
Code:
tolower //function's address
into:
If I use traditional type-casting:
Code:
int (*ptr)(int) = (int (*)(int))tolower;
- everything's fine.
But if I type-casting by means of reinterpret_cast operator:
Code:
int (*ptr)(int) = reinterpret_cast<int (*)(int)>(tolower);
I'm getting the following error:
Quote:
error: overloaded function with no contextual type information
What am I doing wrong ?
Re: [g++] Getting an error while using reinterpret_cast operator
There is no need for a cast in the first place, since a pointer to the non-template version of tolower as borrowed from the C standard library is already of type int (*)(int). But if it was not... I do not think that such function pointer conversions are well defined.
Re: [g++] Getting an error while using reinterpret_cast operator
Quote:
Originally Posted by
laserlight
There is no need for a cast in the first place, since a pointer to the non-template version of tolower as borrowed from the C standard library is already of type int (*)(int).
Yes, it is, but there is a problem when we use this name in transform function in g++:
Code:
#include <algorithm>
#include <string>
#include <cctype>
using namespace std;
int main()
{
string a;
transform(a.begin(), a.end(),
a.begin(), tolower);
}
We're getting the following error:
Quote:
error: no matching function for call to 'transform(__gnu_cxx::__normal_iterator<char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >,
__gnu_cxx::__normal_iterator<char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >,
__gnu_cxx::__normal_iterator<char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >,
<unresolved overloaded function type>)'
Quote:
Originally Posted by
laserlight
But if it was not... I do not think that such function pointer conversions are well defined.
Why do you think so ? Comeau C++ Online doesn't show any errors in the example with reinterpret_cast operator...
Re: [g++] Getting an error while using reinterpret_cast operator
Sounds like a problem with g++. That code compiles fine with both MSVC and Comeau's online compiler.
Quote:
Why do you think so ? Comeau C++ Online doesn't show any errors in the example with reinterpret_cast operator...
He's talking about function pointer conversions in general. You can just as easily change that line to be something totally different and blatantly wrong, like
Code:
int* ptr = reinterpret_cast<int*>(tolower);
and the compiler still won't complain, because reinterpret_cast basically lets you blindly convert one pointer to another.
Re: [g++] Getting an error while using reinterpret_cast operator
What happens if you do this:
Code:
#include <algorithm>
#include <string>
#include <cctype>
using namespace std;
int main()
{
string a;
transform(a.begin(), a.end(),
a.begin(), ::tolower);
}
Re: [g++] Getting an error while using reinterpret_cast operator
Quote:
Originally Posted by
Speedo
Sounds like a problem with g++. That code compiles fine with both MSVC and Comeau's online compiler.
Exactly...
Quote:
Originally Posted by
Speedo
He's talking about function pointer conversions in general. You can just as easily change that line to be something totally different and blatantly wrong
I know, but in my type-casting which I'm doing by means of reinterpret_cast operator, the new type (here it is int (*)(int)) is exactly the same as while doing type-casting by means of traditional way. (Look at my 1# post)...
Re: [g++] Getting an error while using reinterpret_cast operator
Quote:
Originally Posted by
Lindley
What happens if you do this:
Thanks, it helped :)
Can you explain me why :: operator is the solution :confused:
Re: [g++] Getting an error while using reinterpret_cast operator
Because in C++, there are multiple versions of tolower. The version from the C library lives in the global namespace, and has the signature you expect; but there's also a version which is templated to accept a locale, and that lives in the std namespace.
When you call tolower() with an argument, the compiler is able to figure out which one to use. But when you simply take a pointer to it, that isn't so clear----unless you do something to disambiguate the situation.
In this case, :: tells the compiler to use the version in the global namespace, which is the C version.
Re: [g++] Getting an error while using reinterpret_cast operator
Quote:
Originally Posted by
Lindley
Because in C++, there are multiple versions of tolower. The version from the C library lives in the global namespace, and has the signature you expect; but there's also a version which is templated to accept a locale, and that lives in the std namespace.
When you call tolower() with an argument, the compiler is able to figure out which one to use. But when you simply take a pointer to it, that isn't so clear----unless you do something to disambiguate the situation.
In this case, :: tells the compiler to use the version in the global namespace, which is the C version.
Awesome catch. This is a good example of why it is better to not use the "using namespace std" at the file scope as the OP has. I prefer to just type the namespace each time or add the using declaration at function scope for the specific things that I want to use in that function.
Re: [g++] Getting an error while using reinterpret_cast operator
Quote:
Originally Posted by Lindley
The version from the C library lives in the global namespace
I do not think that that is guaranteed to be true, not if you #include <cctype>: the version of tolower from the C standard library is guaranteed to be available in the std namespace, but not in the global namespace. If you #include <ctype.h> instead, then you would indeed be guaranteed that tolower will be available in the global namespace, but this is a deprecated feature (although it will continue to be available in the foreseeable future, in my opinion, since it is likely that C++ compilers will continue to be provided alongside C compilers from the same vendor).
I have encountered what Quentin026 experienced with precisely the same thing for g++, and this might also have been mentioned by Josuttis in The C++ Standard Library. Yes, I observed that using ::tolower fixed the compile error, but after considering what the standard guarantees about <cctype>, I decided that a better approach is to write a function object wrapper for tolower. There is also the consideration that you may indeed want to make use of the locale, in which case a function object can be tweaked to provide the necessary scaffolding.
Now, the next question: what's with the difference between MSVC and the Comeau online compiler versus g++?
Re: [g++] Getting an error while using reinterpret_cast operator
Quote:
Originally Posted by
Lindley
In this case, :: tells the compiler to use the version in the global namespace, which is the C version.
Don't forget that I've used use namespace std;, so now, global namespace = std namespace...
Quote:
Originally Posted by
kempofighter
I prefer to just type the namespace each time or add the using declaration at function scope for the specific things
Using declaration is something like this ?
Code:
using std::cout;
using std::cin;
Quote:
Originally Posted by
laserlight
after considering what the standard guarantees about <cctype>, I decided that a better approach is to write a function object wrapper for tolower.
Is it what you had in mind ? :)
Code:
#include <iostream>
#include <algorithm>
#include <string>
#include <cstdlib>
using namespace std;
char my_tolower(char c)
{
return tolower(c);
}
//-------------------------------------------
int main()
{
string a;
transform(a.begin(), a.end(),
a.begin(), my_tolower);
}
//-------------------------------------------
Quote:
Originally Posted by
laserlight
Now, the next question: what's with the difference between MSVC and the Comeau online compiler versus g++?
Developers of g++ have added some overload functions - that's all...
Re: [g++] Getting an error while using reinterpret_cast operator
I think the problem is overzealous includes.
From just including cctype, are included:
Code:
int tolower ( int c );
int std::tolower ( int c );
template <class charT> charT std::tolower ( charT c, const locale& loc );
That's 2 of 3 functions that should NOT have been imported...
Re: [g++] Getting an error while using reinterpret_cast operator
Quote:
Originally Posted by Quentin026
Don't forget that I've used use namespace std;, so now, global namespace = std namespace...
No, a using directive makes the names from the given namespace available in the scope of the using directive, without qualification. It does not make one namespace equal to another, hence names from the various namespaces can still be fully qualified as needed.
Quote:
Originally Posted by Quentin026
Using declaration is something like this ?
Yes.
Quote:
Originally Posted by Quentin026
Is it what you had in mind ?
Yes, but that is a function, not a function object. For your purposes the difference does not matter.
Quote:
Originally Posted by Quentin026
Developers of g++ have added some overload functions - that's all...
With my copy of g++, tolower from <ctype.h> is made available in the std namespace via a using declaration in <cctype>. However, it is still available in the global namespace, when it arguably should not be. (Actually, g++ compiles your original code perfectly fine for me, until I #include <locale>, which is what is supposed to be needed for the template versions of std::tolower anyway.)
Re: [g++] Getting an error while using reinterpret_cast operator
Quote:
Originally Posted by
laserlight
No, a using directive makes the names from the given namespace available in the scope of the using directive, without qualification. It does not make one namespace equal to another
Sorry, my mistake :)
Quote:
Originally Posted by
laserlight
Yes, but that is a function, not a function object. For your purposes the difference does not matter.
Why would I need use a function object ? If I wanted to use that construction, I unnecessarily would have to define a class - when I don't need one...
Re: [g++] Getting an error while using reinterpret_cast operator
Quote:
Originally Posted by Quentin026
Why would I need use a function object ?
To make use of locales.