-
July 20th, 2010, 02:09 PM
#1
[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:
error: overloaded function with no contextual type information
What am I doing wrong ?
-
July 20th, 2010, 02:20 PM
#2
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.
Last edited by laserlight; July 20th, 2010 at 02:24 PM.
-
July 20th, 2010, 04:05 PM
#3
Re: [g++] Getting an error while using reinterpret_cast operator
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:
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>)'
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...
-
July 20th, 2010, 04:20 PM
#4
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.
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.
-
July 20th, 2010, 05:00 PM
#5
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);
}
-
July 20th, 2010, 05:11 PM
#6
Re: [g++] Getting an error while using reinterpret_cast operator
Originally Posted by Speedo
Sounds like a problem with g++. That code compiles fine with both MSVC and Comeau's online compiler.
Exactly...
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)...
-
July 20th, 2010, 05:14 PM
#7
Re: [g++] Getting an error while using reinterpret_cast operator
Originally Posted by Lindley
What happens if you do this:
Thanks, it helped
Can you explain me why :: operator is the solution
-
July 20th, 2010, 05:27 PM
#8
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.
-
July 20th, 2010, 07:32 PM
#9
Re: [g++] Getting an error while using reinterpret_cast operator
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.
-
July 20th, 2010, 10:43 PM
#10
Re: [g++] Getting an error while using reinterpret_cast operator
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++?
-
July 21st, 2010, 02:02 AM
#11
Re: [g++] Getting an error while using reinterpret_cast operator
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...
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;
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);
}
//-------------------------------------------
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...
-
July 21st, 2010, 02:42 AM
#12
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...
Is your question related to IO?
Read this C++ FAQ article at parashift by Marshall Cline. In particular points 1-6.
It will explain how to correctly deal with IO, how to validate input, and why you shouldn't count on "while(!in.eof())". And it always makes for excellent reading.
-
July 21st, 2010, 02:52 AM
#13
Re: [g++] Getting an error while using reinterpret_cast operator
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.
Originally Posted by Quentin026
Using declaration is something like this ?
Yes.
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.
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.)
Last edited by laserlight; July 21st, 2010 at 02:55 AM.
-
July 21st, 2010, 04:36 AM
#14
Re: [g++] Getting an error while using reinterpret_cast operator
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
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...
-
July 21st, 2010, 05:17 AM
#15
Re: [g++] Getting an error while using reinterpret_cast operator
Originally Posted by Quentin026
Why would I need use a function object ?
To make use of locales.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|