This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug c++/20414] New: C-style cast fails to do proper conversion (explicit type conversion)


It seems that g++ is not compliant with the standard for old-style C casts -
potentially causing programs to crash.

Below is a code sample followed by an detailing of what happens in practice, and
what I think should happen. Cast#5 is the problematic cast.

======== CODE STARTS HERE =========

#include <iostream>

struct B
{
  B (const char *s):str (s)
  {
  }
  const char *str;
};
struct H
{
  H (const char *s)
  {
    strcpy (str, s);
  }
  operator const B ()
  {
    return B (str);
  }
  char str[1024];
};

void
f (const B & b)
{
  std::cout << b.str << std::endl;
}

int
main (int argc, char *argv[])
{
  H h ("hi4243");
  
  // cast #1: initialization by conversion for reference binding OK
  const B &b = h;

  // cast #2: direct-initialization
  const B b2(h);

  // cast #3: explicit static_cast OK
  f (static_cast<const B &>(h));

  // cast #4: C-style cast, works as expected OK
  f ((const B)h);

  // cast #5: C-style cast, should cause an implicit conversion sequence,
  // but it does not ERROR!! program will crash
  f ((const B &)h);
  
  return 0;
}

======== CODE ENDS HERE =========

Here is what g++ does for each cast:

#1 - call the conversion operator in H to turn 'h' to type B and then proceed
using a standard conversion sequence. This is compliant with "Section 13.3.1.6
Initialization by conversion function for direct reference binding" of the standard.

#2 - essentially does the same as #1, but is there to show the validity of the
static_cast in cast #3 based on "Section 5.2.9 Static cast clause 2" of the
standard. The process itself is described in "Section 8.5 clauses 12 and 14" of
the standard.

#3 - performs an explicit static_cast to a reference type. Cast #2 shows that
this is well-formed.

#4 - performs a cast using the user-defined conversion operator as expected.

#5 - performs the equivalent of a reinterpret_cast. This causes the program to
crash. 

The standard is clear in saying that when an old-style C-cast("explicit type
conversion"/"cast notation") is used, the compiler should attempt the conversion
 -exactly- in this order: const_cast, static_cast, static_cast followed by
const_cast, reinterpret_cast, and reinterpret_cast followed by a const_cast. It
goes on to say that if more than one cast is possible, the -first- one in this
list should be used.

The code sample above shows that a static_cast works properly(#3), but an
explicit cast(#5) fails to detect the possibility of using a static_cast;
moreover, cast #4 seems to indicate that the problem is g++'s failure to do a
standard conversion sequence before looking up the user-defined conversion
operator in H.

I might be misreading or misunderstanding the standard, so if that is the case,
please let me know.

Thanks,
Simon

-- 
           Summary: C-style cast fails to do proper conversion (explicit
                    type conversion)
           Product: gcc
           Version: 3.4.3
            Status: UNCONFIRMED
          Severity: normal
          Priority: P2
         Component: c++
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: simonc235 at yahoo dot com
                CC: gcc-bugs at gcc dot gnu dot org


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20414


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]