#1
  1. No Profile Picture
    Junior Member
    Devshed Newbie (0 - 499 posts)

    Join Date
    Aug 2003
    Posts
    14
    Rep Power
    0

    Function overload using typedefs problem.


    Code that doesn't compile:

    #include <iostream.h>

    typedef char * cstring;

    void routine(cstring in) {
    cout<<"routine(cstring in): "<<in<<endl;
    }

    void routine(const cstring in) {
    cout<<"routine(const cstring in): "<<in<<endl;
    }

    void main(void) {
    cstring x = "char *";
    routine(x);
    routine("const char *");
    }

    Result:

    test.cpp: In function `void routine(char *)':
    test.cpp:9: redefinition of `void routine(char *)'
    test.cpp:5: `void routine(char *)' previously defined here


    Code that compiles:

    #include <iostream.h>

    void routine(char * in) {
    cout<<"routine(char * in): "<<in<<endl;
    }

    void routine(const char * in) {
    cout<<"routine(const char * in): "<<in<<endl;
    }

    void main(void) {
    cstring x = "char *";
    routine(x);
    routine("const char *");
    }

    Result:

    routine(char * in): char *
    routine(const char * in): const char *

    I have tryed this test with GCC 2.95.1 and 3.3. Both produce the same results. Anyone have any insight or suggestions? I did attempt a third test with a typedef for "const char *" and that seemed to work.
  2. #2
  3. No Profile Picture
    Junior Member
    Devshed Newbie (0 - 499 posts)

    Join Date
    Aug 2003
    Posts
    14
    Rep Power
    0

    Another test...


    Just tryed Visual Studio 6... same results.

    test.cpp
    C:\CurrentProjects\test\test.cpp(14) : error C2084: function 'void __cdecl routine(char *)' already has a body
  4. #3
  5. No Profile Picture
    Contributing User
    Devshed Beginner (1000 - 1499 posts)

    Join Date
    Feb 2001
    Posts
    1,472
    Rep Power
    15
    Hi,

    I can get you part of the way there:

    void routine(cstring in)
    void routine(const cstring in)

    The parameter of the first function is "pointer to char" (=char*) but the parameter of the second function is not "pointer to constant char"(=const char*), it's really constant "pointer to char"(=char* const). In other words, you're making the char pointer constant when you say: const cstring--you're not tacking on a const specifier in front of char*. So, your functions really look like this:

    void routine(char* in)
    void routine(char* const in)

    The difference between a pointer to a constant and a constant pointer is that in the first case, you cannot change what the pointer points to, but you can make the pointer point to a different location. On the other hand, a constant pointer cannot be made to point to a different location, but you can change what it points to.

    Now, the question is why does the compiler see those parameters as the same type? A constant pointer could not be sent to the first function, because the function could try to change the pointer, but a pointer to char could be sent to both functions. A pointer to a char can be sent to the second function because the parameter is saying it won't change where the pointer points, which doesn't violate any restrictions for a pointer to char. The result is the compiler must be complaining about that ambiguity.
    Last edited by 7stud; August 8th, 2003 at 05:12 PM.
  6. #4
  7. No Profile Picture
    Junior Member
    Devshed Newbie (0 - 499 posts)

    Join Date
    Aug 2003
    Posts
    14
    Rep Power
    0
    Heh, it didn't even occur to me that the typedef would behave any differently than a macro... but it makes sense. Also explains the ambiguity issue as well. :)

    Now to decide what to do.

    Thanks!
  8. #5
  9. No Profile Picture
    Contributing User
    Devshed Beginner (1000 - 1499 posts)

    Join Date
    Feb 2001
    Posts
    1,472
    Rep Power
    15
    On second thought, I'm not sure the ambiguity does explain it--your second program compiles fine, and that same ambiguity seems to be present there.
  10. #6
  11. No Profile Picture
    Junior Member
    Devshed Newbie (0 - 499 posts)

    Join Date
    Aug 2003
    Posts
    14
    Rep Power
    0
    "char *" and "const char *" are distinct. "char *" and "char * const" are not. :)
  12. #7
  13. No Profile Picture
    Contributing User
    Devshed Beginner (1000 - 1499 posts)

    Join Date
    Feb 2001
    Posts
    1,472
    Rep Power
    15
    Ok, I found the explanation in my book:

    1)For pointers and references, overloaded functions are different if one of them has a type "pointer to type" and the other has a parameter "pointer to const type".

    2)Two overloaded functions are the same if one parameter is of type "pointer to type" and the other is of type const "pointer to type".

    The reason has to do with the pass-by-value mechanism. With a basic type, the parameters "int" and "const int" are the same because the function gets a copy of the original, so it cannot modify the original and therefore the const specifier is superfluous.

    The pass-by-value mechanism also operates with pointers--a copy of the original pointer is sent to the function. But with pointers, the function is able to modify the value pointed to by the original pointer since the copy and the original both point to the same thing, so "pointer to type" and "pointer to const type" are different--the latter will prevent the function from modifying the value pointed to by the pointer. However, there is no need to prevent the function from changing where the original pointer is pointing, i.e making the pointer itself constant, because the function has a copy and changing where the copy points has no effect on the original pointer, so the const specifier is superfluous.
    Last edited by 7stud; August 8th, 2003 at 05:18 PM.
  14. #8
  15. No Profile Picture
    Contributing User
    Devshed Beginner (1000 - 1499 posts)

    Join Date
    Feb 2001
    Posts
    1,472
    Rep Power
    15
    lol...you already knew it.
  16. #9
  17. No Profile Picture
    Junior Member
    Devshed Newbie (0 - 499 posts)

    Join Date
    Aug 2003
    Posts
    14
    Rep Power
    0
    Just for anyone else who's curious, or has any doubts:

    SOURCE:
    typedef char * cstring;
    void my_routine(const cstring in) { }
    MANGLED NAME:
    my_routine__FPc

    SOURCE:
    void my_routine(char * const in) { }
    MANGLED NAME:
    my_routine__FPc

    SOURCE:
    void my_routine(const char * in) { }
    MANGLED NAME:
    my_routine__FPCc

    Thanks for helping 7stud... you the man! :)

IMN logo majestic logo threadwatch logo seochat tools logo