From 811262261262108536
X-Google-Language: ENGLISH,ASCII-7-bit
X-Google-Thread: f78e5,da1ccb8620d6613e,start
X-Google-Attributes: gidf78e5,public
From: "Bill Wade" <bill.wade@stoner.com>
Subject: A use for const references?
Date: 1997/08/19
Message-ID: <01bcacad$1439e730$2864370a@janeway>#1/1
X-Deja-AN: 265361222
X-Original-Date: 19 Aug 1997 14:35:04 GMT
Organization: NeoSoft, Inc.
X-Auth: PGPMoose V1.1 PGP comp.std.c++ iQBVAwUBM/oLfky4NqrwXLNJAQF56AH+Lx8xTEX+ubREHpNbplxrf6PX/fgIGGHW gtWi8Z/HtbgFbA8PIazO4WW+6PzuGhzfZVyu2mLDqdGU/cU1I9i8Lg== =StsT
Newsgroups: comp.std.c++
Originator: austern@isolde.mti.sgi.com


Consider the following:

struct foo1
{
  foo(int& ii):i(ii){}
  const int i;		// Non-static member
};

void fuzz1(foo1&);
bool bar1(foo1& f)
{
  int o = f.i;
  fuzz1(f);
  return o == f.i;
}

I believe that a compiler can optimize bar to always return true (avoid the
final comparison).  If fuzz modifies f.i using a cast the results are
undefined.  Likewise if fuzz destructs and reconstructs f: from 3.8.9:

 "Creating a new object at the storage location that a const object with
  static or automatic storage duration occupies or, at the storage loca-
  tion that such a const object used to occupy before its lifetime ended
  results in undefined behavior."

Since f.i is a const object, you get undefined behavior if you reconstruct
f in place.  I believe this means that the compiler can assume that fuzz.i
won't change its value.  Please correct me if I'm wrong.

Now consider

struct foo2
{
  foo2(int& ii):i(ii){}
  int& i;
};

void fuzz2(foo2&);
bool bar2(foo2& f)
{
  int* o = &f.i;
  fuzz2(f);
  return o == &f.i;
}

I don't believe the compiler can optimize bar2 (at least if fuzz2 is in
another compilation unit).  It is perfectly legal for fuzz2 destruct and
reconstruct its argument, possibly changing the value of (&f.i).  
It isn't really necessary to pass f to fuzz2 for the problem to arise,
fuzz2 may have access to f through some other route (aliasing problem). 
However if the reference were const (a const reference, not a reference to
const) the optimization could be reinstated.  In other words

struct foo2
{
  foo2(int& ii):i(ii){}
  int& const i;
};

would allow bar2() to avoid the final comparision.  Do I have this right? 

Now I'll try to sneak in a non comp.std.c++ question.  Does anyone know of
compilers which perform either or both of these optimizations?  How about
compilers which do the foo2 optimization even if the reference is not
const?
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your 
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu 
]



