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

Geoffrey Keating geoffk@apple.com
Wed Oct 13 23:19:00 GMT 2004


On 13/10/2004, at 2:54 PM, Gabriel Dos Reis wrote:

> Geoffrey Keating <geoffk@apple.com> writes:
>
> | On 13/10/2004, at 1:39 PM, Gabriel Dos Reis wrote:
> |
> | > Geoffrey Keating <geoffk@apple.com> writes:
> | >
> | > | On 12/10/2004, at 8:42 PM, Gabriel Dos Reis wrote:
> | > |
> | > | > The code in build_string
> | > | >
> | > | >   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';
> | > | >
> | > | > is trying to do similar thing, but it is undefined behaviour.
> | > | >
> | > | >        [#5] If an attempt is made to modify an object defined  
> with
> | > | >        a  const-qualified  type  through use of an lvalue with 
> non-
> | > | >        const-qualified type, the  behavior  is  undefined.
> | > |
> | > | The object here is '*s', which was not defined with a 
> const-qualified
> | > | type.  It's not defined with any type at all, it was allocated
> | > through
> | > | malloc which is not a typed interface.  (It would be different 
> if it
> | > | was allocated through 'new', but we do not have new in C.)
> | >
> | > The undefined behaviour comes from different sources.
> | > Consider the following:
> | >
> | >    typedef struct {
> | >       int fu;
> | >       const int bhar;
> | >    } S;
> | >
> | >    void f(S *p)
> | >    {
> | >        (*p).fu = 90;            // #1
> | >    }
> | >
> | > Do you believe line #1 is valid in face of
> | >
> | >        [#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.
> | >
> | > ?
> |
> | Yes.  The lvalue here is '(*p).fu', which has type 'int' and 
> therefore
> | is a modifiable lvalue.
>
> No.  The lvalue *p, of type S, is not modifiable.

There is nothing in the standard that says the left-hand argument to 
'.' must be modifiable.  Generally, only left-hand arguments to '=' 
(and similar things, like '++') must be modifiable lvalues.

> | Note that '*p' is not a modifiable lvalue, but all of '*p' is not
> | being modified here.
>
> I guess this is where our disagreement lies: It does not matter
> whether the lvalue is used to modify a small part of the whole object.

I don't believe the word 'object' appears in the relevant constraints.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/pkcs7-signature
Size: 2408 bytes
Desc: not available
URL: <https://gcc.gnu.org/pipermail/gcc/attachments/20041013/b18b3537/attachment.p7s>


More information about the Gcc mailing list