Bug report: gcc 2.95 backwards incompatible w.r.t. 2.7.2.2

Robert Karban rkarban@eso.org
Tue Aug 31 22:45:00 GMT 1999


*) problem:
=======
If a const cast in a template class is defined and
used as simple cast without const qualifier then
the cast operator is NOT called when the type is
a character array. Instead something else is called.

If the instantiated type is a basic type it works.
This is bad if you rely on calling the operator.

Does anyone know what's wrong here?
The behaviour doesn't seem to be logical nor consistent
and moreover backwards incompatible, since it worked fine
with gcc 2.7.2.2

Additionally in gcc 2.7 it was also sufficient to assign a const
reference
to
a non const value. In gcc 2.95 on hast to cast away the const.
See constructot of class.
That seems also be wrong.

Thanks.
Robert Karban
rkarban@eso.org

*) gcc version:
===========
Reading specs from
/vlt/gnu-exp/lib/gcc-lib/hppa1.1-hp-hpux10.20/2.95/specs
gcc version 2.95 19990728 (release)

Reading specs from
/vlt/gnu/lib/gcc-lib/hppa1.1-hp-hpux10.20/2.7.2.2/specs
gcc version 2.7.2.2

*) gcc command line:
================
gcc -ansi -Wall cast2.C -o cast2 -lstdc++

*) system:
=======
HP-UX 10.20

*) code:
======
#include <stdio.h>
#include <stdlib.h>
#include <iostream.h>

typedef unsigned char      BYTES20[20];
typedef int                INT32;
typedef unsigned int       UINT32;

template<class T>
class TEST
{
  public:
    T                 value;

#if (__GNUC_MINOR__ == 7)

    // gcc 2.7.2.2 works fine with this
    TEST(const T &newVal) { value = newVal; }

#elif (__GNUC_MINOR__ == 95)

    // gcc 2.95 needs this
    TEST(const T &newVal) { value = const_cast<T &>(newVal); }

#else
#error unknown gcc version
#endif

    operator  const T&()
    {
 cout << "====> in operator const()\n";
 return value;
    }
};

int main(int, char *argv[])
{
    {
    cout << "\n===== Testing INT32 ======\n";

    TEST<INT32> vector(123);

    cout << "cast value without const (why is const operator called)\n";
    cout << " " << (INT32) vector;
    cout << "\n";
    }

    {
    cout << "\n===== Testing BYTES20 ======\n";

    BYTES20 array;
    strcpy((char*) array, "456");

    TEST<BYTES20> vector(array);

    cout << "cast value without const (what cast is called)\n";
    cout << " " << (BYTES20&) vector;
    cout << "\n";

    cout << "cast value with const\n";
    strcpy((char*) array, "000");
    strcpy((char*) array, (const char *)(const BYTES20&) vector);
    cout << "value =  " << array;

    cout << "\ncast value without const (operator not called!)\n";
    strcpy((char*) array, "000");
    strcpy((char*) array, (const char *)(BYTES20&) vector);
    cout << "value =  " << array;

    cout << "\nEND\n";
    }
    cout.flush();
} /* end main() */

*) Output gcc 2.95:
===============
===== Testing INT32 ======
cast value without const (why is const operator called)
 ====> in operator const()
123

===== Testing BYTES20 ======
cast value without const (what cast is called)
 456
cast value with const
====> in operator const()
value =  456
cast value without const (operator not called!)
value =  456
END

*) Output gcc 2.7.2.2:
==================
===== Testing INT32 ======
cast value without const (why is const operator called)
 ====> in operator const()
123

===== Testing BYTES20 ======
cast value without const (what cast is called)
 ====> in operator const()
456
cast value with const
====> in operator const()
value =  456
cast value without const (operator not called!)
====> in operator const()
value =  456
END



More information about the Gcc-bugs mailing list