CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 15 of 15
  1. #1
    Join Date
    Jul 2009
    Posts
    28

    Exclamation [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:

    Code:
    (int (*)(int))
    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 ?

  2. #2
    Join Date
    Jan 2006
    Location
    Singapore
    Posts
    6,765

    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.
    C + C++ Compiler: MinGW port of GCC
    Build + Version Control System: SCons + Bazaar

    Look up a C/C++ Reference and learn How To Ask Questions The Smart Way
    Kindly rate my posts if you found them useful

  3. #3
    Join Date
    Jul 2009
    Posts
    28

    Re: [g++] Getting an error while using reinterpret_cast operator

    Quote Originally Posted by laserlight View Post
    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>)'
    Quote Originally Posted by laserlight View Post
    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...

  4. #4
    Join Date
    Aug 2007
    Posts
    858

    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.

  5. #5
    Lindley is offline Elite Member Power Poster
    Join Date
    Oct 2007
    Location
    Seattle, WA
    Posts
    10,895

    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);
    }

  6. #6
    Join Date
    Jul 2009
    Posts
    28

    Re: [g++] Getting an error while using reinterpret_cast operator

    Quote Originally Posted by Speedo View Post
    Sounds like a problem with g++. That code compiles fine with both MSVC and Comeau's online compiler.
    Exactly...

    Quote Originally Posted by Speedo View Post
    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)...

  7. #7
    Join Date
    Jul 2009
    Posts
    28

    Re: [g++] Getting an error while using reinterpret_cast operator

    Quote Originally Posted by Lindley View Post
    What happens if you do this:
    Thanks, it helped

    Can you explain me why :: operator is the solution

  8. #8
    Lindley is offline Elite Member Power Poster
    Join Date
    Oct 2007
    Location
    Seattle, WA
    Posts
    10,895

    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.

  9. #9
    Join Date
    Aug 2005
    Location
    San Diego, CA
    Posts
    1,054

    Lightbulb Re: [g++] Getting an error while using reinterpret_cast operator

    Quote Originally Posted by Lindley View Post
    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.

  10. #10
    Join Date
    Jan 2006
    Location
    Singapore
    Posts
    6,765

    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++?
    C + C++ Compiler: MinGW port of GCC
    Build + Version Control System: SCons + Bazaar

    Look up a C/C++ Reference and learn How To Ask Questions The Smart Way
    Kindly rate my posts if you found them useful

  11. #11
    Join Date
    Jul 2009
    Posts
    28

    Re: [g++] Getting an error while using reinterpret_cast operator

    Quote Originally Posted by Lindley View Post
    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 View Post
    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 View Post
    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 View Post
    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...

  12. #12
    Join Date
    Jun 2009
    Location
    France
    Posts
    2,513

    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.

  13. #13
    Join Date
    Jan 2006
    Location
    Singapore
    Posts
    6,765

    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.)
    Last edited by laserlight; July 21st, 2010 at 02:55 AM.
    C + C++ Compiler: MinGW port of GCC
    Build + Version Control System: SCons + Bazaar

    Look up a C/C++ Reference and learn How To Ask Questions The Smart Way
    Kindly rate my posts if you found them useful

  14. #14
    Join Date
    Jul 2009
    Posts
    28

    Re: [g++] Getting an error while using reinterpret_cast operator

    Quote Originally Posted by laserlight View Post
    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 View Post
    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...

  15. #15
    Join Date
    Jan 2006
    Location
    Singapore
    Posts
    6,765

    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.
    C + C++ Compiler: MinGW port of GCC
    Build + Version Control System: SCons + Bazaar

    Look up a C/C++ Reference and learn How To Ask Questions The Smart Way
    Kindly rate my posts if you found them useful

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured