This is the mail archive of the gcc@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]

Re: Compiling GCC With a C++ Compiler (g++)


Andreas Schwab <schwab@suse.de> writes:

| Gabriel Dos Reis <gdr@cs.tamu.edu> writes:
| 
| > The fact that the subboject is part of a "whole writebale" object does
| > not make the subobject suddenly writable.
| 
| But it is writable in the first place.  Just because a const-qualified
| lvalue is used in some places does not make the object suddenly read-only.


Sure, Look at the language I quote below.

| > Looking more closely the language in 6.3.2.1.
| >
| >        [#1]  An  lvalue  is an expression with an object type or an
| >        incomplete  type  other  than void;53) if an lvalue does not
| >        designate an object when it is evaluated,  the  behavior  is
| >        undefined.   When  an  object  is  said to have a particular
| >        type, the type is specified by the lvalue used to  designate
| >        the  object.  A modifiable lvalue is an lvalue that does not
| >        have array type, does not have an incomplete type, does  not
| >        have  a  const-qualified  type,  and if it is a structure or
| >        union, does not have any member (including, recursively, any
| >        member  or  element  of  all contained aggregates or unions)
| >        with a const-qualified type.
| >
| >
| > This language makes any lvalue whose type is whole tree_string
| > non-modifiable (this rule is very different from C++).
| 
| ... through that const-qualified lvalue.  But you can create a different
| lvalue (by casting) through which you can modify the object.

Look at the current implementation of build_string

    tree
    build_string (int len, const char *str)
    {
      tree s;
      size_t length;

      length = len + sizeof (struct tree_string);

    #ifdef GATHER_STATISTICS
      tree_node_counts[(int) c_kind]++;
      tree_node_sizes[(int) c_kind] += length;
    #endif  

      s = ggc_alloc_tree (length);

      memset (s, 0, sizeof (struct tree_common));
      TREE_SET_CODE (s, STRING_CST);
      TREE_STRING_LENGTH (s) = len;
      memcpy ((char *) TREE_STRING_POINTER (s), str, len);
      ((char *) TREE_STRING_POINTER (s))[len] = '\0';

      return s;
    }

The lvalue "s" is just nonmodifiable aoocording to the above language.

And the situation get worse as tree_string is also a member of
tree_node, and therefore this change affects all other uses of the
union tree_node that modify its value.

| 
| > Interestingly, while this appear in the section on "restrict", it
| > gives you food for thought
| 
| I don't see any restrict qualification here.

Which is probably why I do not give it as the main justification of
why Geoff's change introduces undefined behaviour?

We need to bring the header back to the intersection of C and C++.

-- Gaby


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