Template function and const array of chars

Discussion in 'C++' started by Milan Cvetkovic, Mar 22, 2006.

  1. Hi,

    Recently I came accross a weird bug in my code which turned to be my
    missunderstanding of arrays in C++. It all boils down to the small example:


    template<class ITER>
    const char* gggg (ITER value)
    {
    return value;
    }

    int main (int /*argc*/, char* /*argv*/[])
    {
    const char array[] = "ABCD";
    const char* p1 = gggg(array);
    const char* p2 = gggg(array+0);
    if (p1 == p2)
    return 0;
    else
    return 1;
    }

    This program will report different results when compiled with different
    compiler. In particular, g++-2.95.2 returns 1 (pointers are not equal)
    and g++-4.1 returns 0 (pointers are equal).

    Is this a compiler bug in 2.95.2, or the C++ spec allows the compiler do
    this funny stuff.

    Thanks, Milan.
     
    Milan Cvetkovic, Mar 22, 2006
    #1
    1. Advertisements

  2. Milan Cvetkovic

    Tomás Guest

    template<class T>
    const char* TakeByValueAndConvertToCharPointer (T object)
    {
    return object;
    }

    int main()
    {
    char const array[] = "ABCD";

    /*
    Right now, we have an array in
    memory that looks like as follows:

    -------------------------------
    | 'A' | 'B' | 'C' | 'D' | 0 |
    -------------------------------

    */

    const char* p1 = gggg(array);

    //In the above line, you've just passed an array by value.
    //If memory serves me right, that's dodgy.

    const char* p2 = gggg(array+0);

    //In the above line, it looks like "array" will decay to
    //an expression of type "const char*", and then zero will
    //be added to it.

    if (p1 == p2)
    return 0;
    else
    return 1;
    }

    -Tomás
     
    Tomás, Mar 22, 2006
    #2
    1. Advertisements

  3. I don't know what exactly you mean by "dodgy".
    Isn't this usage same as when you write:

    printf ("This is a string\n");

    The function gggg is instantiated with <const char*> as a parameter, in
    both invocations. The value of parameter passed depends on:
    - compiler used; and
    - the invocation (arrray or array+0)

    Milan.
     
    Milan Cvetkovic, Mar 22, 2006
    #3
  4. No, arrays can't be passed by value directly - one would have to wrap
    it in a class to do so. Just the decayed pointer will be passed.

    [snip]
    Sorry to be dense, but I'm missing your point. Based on your analysis,
    should the program return 0 or 1? That was the OP's question.

    Best regards,

    Tom
     
    Thomas Tutone, Mar 22, 2006
    #4
  5. As far as I can tell, both calls refer to the same function 'gggg<const
    char *>(const char *)' and supply it with the same arguments. 'p1' and
    'p2' should be equal.

    On VS8.0, 'main' returns 0.

    I'd say it's a compiler bug; the old g++ may have problems deducing
    correct template arguments.
     
    Martin Vejnar, Mar 22, 2006
    #5
  6. Milan Cvetkovic

    AnalogFile Guest

    I guess G++-2.95.2 failed to comply with 14.8.2.1/2 and instantiated the
    first call with the wrong type.

    I guess you can test this by forcing an error and looking at the
    compiler diagnostics. For example try

    template<class ITER>
    const char* gggg (ITER value)
    {
    value = 1;
    return value;
    }

    since there's no cast it should give an error and tell you what type
    ITER it's trying to instantiate.
     
    AnalogFile, Mar 22, 2006
    #6
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.