Topic: Destruction of Temporaries, Yet Another Posting


Author: john@bnrmtl.bnr.ca (John Hickin)
Date: Wed, 2 Sep 92 14:30:07 GMT
Raw View
It seems to me that much of the trouble comes from exporting the details of an
object's internal representation from a function that the compiler can apply
automatically to a temporary ojbect.  Simple prevention can avoid most of the
problems:

   1. Avoid exporting the details of an object's internal representation,
      especially when the offending function can be applied automatically by
      the compiler such as the famous String :: operator const char*().
      It is interesting to note that the ANSI String proposal renames this
      function to const char* String :: cStr().

   2. Try to write your code to avoid the generation of temporaries.

Of course one can always generate cases where recommendation 2 will fail you
and I personally don't like the idea a lot as it can really cramp your style.
So here is a modest proposal:

   Make temporaries const objects
   Avoid problems due to their early destruction by making dangerous
   value taking operations non-const.

A compiler using the const temporary approach and a thoughtful programmer
can combine to make code like that of the String example safer:

   class String { public:
       operator const char*(); // NON-const
       String( const char* );
       ...
   };

   String h( "hello " ), w( "world" );
   const char* p = h + w;
   //
   //  compiler flags this statement:
   //     Error: non-const member function applied to (const) temporary object.

Of course this could break a lot of existing code.

--
John Hickin      Bell-Northern Research, Montreal, Quebec
(514) 765-8888   bnrmtl!john@larry.mcrcim.mcgill.edu




Author: jss@lucid.com (Jerry Schwarz)
Date: Wed, 2 Sep 92 17:18:59 GMT
Raw View
In article <1992Sep2.143007.5655@bnrmtl.bnr.ca>, john@bnrmtl.bnr.ca (John Hickin) writes:
|>
|> A compiler using the const temporary approach and a thoughtful programmer
|> can combine to make code like that of the String example safer:
|>
|>    class String { public:
|>        operator const char*(); // NON-const
|>        String( const char* );
|>        ...
|>    };
|>

Making the function that gives the pointer to char a non-const is a mistake.
The function may modify the underlying representation, but it certainly
does not modify the represented character sequence.  There is no
reason that I shouldn't be able to apply it to a const String

|>    String h( "hello " ), w( "world" );
|>    const char* p = h + w;

A careful programmer might have written

 const String h("hello "), w(" world") ;

and be surprised that  (const char*)h isn't allowed.

String with a conversion operator seems to have caught on in this
newsgroup as "the" example for discussing lifetime of temporaries.
It should be noted that because of all the problems associated with
such an operator the x3j16 library working group has decided that
this functionality will be provided by an ordinary member function
and not by a conversion operator.

I believe the use of the implicitly invoked conversion operator
obscures the issue of lifetime of temporaries and that we should
be writing the above example out in full as.

 const char* p = (h+w).pchar();

  -- Jerry Schwarz




Author: pabloh@hpwala.wal.hp.com (Pablo Halpern )
Date: Thu, 3 Sep 1992 14:01:16 GMT
Raw View
In article <1992Sep2.171859.852@lucid.com>, jss@lucid.com (Jerry Schwarz) writes:
|> In article <1992Sep2.143007.5655@bnrmtl.bnr.ca>, john@bnrmtl.bnr.ca (John Hickin) writes:
|> |>
|> |> A compiler using the const temporary approach and a thoughtful programmer
|> |> can combine to make code like that of the String example safer:
|> |>
|> |>    class String { public:
|> |>        operator const char*(); // NON-const
|> |>        String( const char* );
|> |>        ...
|> |>    };
|> |>
|>
|> Making the function that gives the pointer to char a non-const is a mistake.
|> The function may modify the underlying representation, but it certainly
|> does not modify the represented character sequence.  There is no
|> reason that I shouldn't be able to apply it to a const String
|>
|> |>    String h( "hello " ), w( "world" );
|> |>    const char* p = h + w;
|>
|> A careful programmer might have written
|>
|>  const String h("hello "), w(" world") ;
|>
|> and be surprised that  (const char*)h isn't allowed.

Well, until the language support for abstract const is solidified, I
suggest the following:

    class String { public:
       operator char*();             // NON-const
       operator const char*() const; // const
       String( const char* );
       ...
    };

A non-const string can be converted to a non-const char*, a const string
can only be converted to a const char*.  If only conversion to a const
char* is desired, then I agree with Jerry that the non-const version should
be eliminated.

|> I believe the use of the implicitly invoked conversion operator
|> obscures the issue of lifetime of temporaries and that we should
|> be writing the above example out in full as.
|>
|>  const char* p = (h+w).pchar();

I tend to agree, although I am open to opposing views.

|>
|>   -- Jerry Schwarz

--

- Pablo

------------------------------------------------------------------------
Pablo Halpern             (617) 290-3542
HP Waltham                pabloh@hpwarq.wal.hp.com

I am self-employed, so my opinions *do* reflect those of my employer.
However, they may not reflect the opinions of my client.
------------------------------------------------------------------------