Topic: references vs. pointers: an OOD issue


Author: Chelly Green <chelly@eden.com>
Date: 1996/11/12
Raw View
root@nntpa.cb.lucent.com wrote:
>
> I would like to weigh in on the side of Tom on this issue.  We can say
>
>         sizeof (type)
> or
>         sizeof expression
>
> for all types except reference types.  Now, we can't have a
> "reference-typed" expression by fundamental restriction of the
> language;

What do you mean by this?

> but why can't we have a "referenced-typed" type (if you
> forgive my English) as an argument to sizeof?

    typedef char& char_ref;

    size_t size = sizeof (char_ref); // == 1

This makes sense to me. A reference behaves like the type it refers to.
I wouldn't expect this to evaluate to 'sizeof (char*)', because it would
be inconsistent with the following:

    char c;

    char_ref ref = c;

    size_t size = sizeof (ref); // == 1

ref should act like the character 'c' it refers to, including its size.

> For example (assume a machine with 2 byte integers and 4 byte addresses):
>
>         int i, *ip=&i, &ir=i;
>         size_t j;
>
>         j = sizeof (int);       // type; == 2
>         j = sizeof i;           // expr; == 2
>         j = sizeof *ip;         // expr; == 2
>         j = sizeof ir;          // expr; == 2

makes sense

>         j = sizeof (int *);     // type; == 4
>         j = sizeof ip;          // expr; == 4
>         j = sizeof &i;          // expr; == 4
>         j = sizeof &ir;         // expr; == 4

makes sense

>         j = sizeof (&int);      // type;

Huh? This is illegal. Maybe you mean

          j = sizeof (int&);      // type; == 2

Which makes sense and is consistent with the above

> In my opinion, the last sizeof should evaluate to the storage size
> of a reference when it is required to occupy storage, just like
> sizeof behaves when given any other type as an argument.

What use would the storage required for a reference be?

> The fact
> that reference-typed expressions are not part of the language is
> not a good reason for making an exception in the case of
> reference types themselves as an argument to sizeof.

I agree.

> By the way, nothing says the size of a reference has to be the
> same as the size of a pointer but a reasonable implementation
> might make that choice.

As far as I can tell, you cannot directly find the size of a reference,
mainly because it is not an object.

--
Chelly Green | chelly@eden.com | C++ - http://www.eden.com/~chelly
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Tom Payne <thp@cs.ucr.edu>
Date: 1996/11/13
Raw View
Chelly Green <chelly@eden.com> wrote:
: root@nntpa.cb.lucent.com wrote:
[...]
:     typedef char& char_ref;

:     size_t size = sizeof (char_ref); // == 1

: This makes sense to me. A reference behaves like the type it refers to.

Right.  It is the fundamental semantics of a reference (i.e, an
instance of a reference type) to behave exactly like its referrent.

: I wouldn't expect this to evaluate to 'sizeof (char*)', because it would
: be inconsistent with the following:

:     char c;

:     char_ref ref = c;

:     size_t size = sizeof (ref); // == 1

: ref should act like the character 'c' it refers to, including its size.

Exactly, by the fundamental semantics of references.

So, where's the inconsistency?  Perhaps you expect sizeof(ref), which
is simply another way of writing sizeof(c), to be the same as
sizeof(char_ref), which is a special case of sizeof(T), where T
designates a type.  Note, however, that a reference is not a type, but
rather an instance of a reference type.

[...]
: Maybe you mean

:           j = sizeof (int&);      // type; == 2

: Which makes sense and is consistent with the above

: > In my opinion, the last sizeof should evaluate to the storage size
: > of a reference when it is required to occupy storage, just like
: > sizeof behaves when given any other type as an argument.

: What use would the storage required for a reference be?

Perhaps a programmer wants to consider it in making a choice between
passing parameters or return values by reference and passing them by
value.

[...]
: As far as I can tell, you cannot directly find the size of a reference,
: mainly because it is not an object.

Right.  You can't find the address and/or size of a reference because
they aren't objects, and references aren't objects because you can't
find their size and address.


On a related matter, is it the position of the standard that a
reference is a name and not an entity?

  An entity is a value, object, subobject, base class subobject, array
  element, variable, function, set of functions, instance of a function,
  enumerator, type, class member, template, or namespace. [Basic
  Concepts]...  A name is a use of an identifier that denotes an entity
  or label. [Basic Concepts] ...  Note: a reference can be thought of as
  a name of an object.  [8.3.1]

Tom Payne
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: ajenkins@cs.umass.edu (Adam P Jenkins)
Date: 1996/11/13
Raw View
In article <55pl8p$lp8@netlab.cs.rpi.edu> Tom Payne <thp@cs.ucr.edu> writes:

> In comp.std.c++ Bradd W. Szonye <bradds@concentric.net> wrote:
> :
> : I really don't understand all the fuss over sizeof(T&). The main _use_ of
> : sizeof is to determine the amount of storage the object takes for arrays
> : (or a comparable array of char or unsigned char) or copying. You can't put
> : a reference in an array, and you can't copy one. Perhaps sizeof(T&) should
> : be illegal, since it can't be put to any good use. The idea that it should
> : return the size of something that you can't copy or put into any array is
> : silly, however. It's not even useful for calculating the size of an object
> : from its sub-objects (since that doesn't work anyway) or for calculating
> : offsetof().
>
> : Perhaps if someone explained _why_ you'd want to know sizeof(T&)--for
> : practical reasons--it would make more sense.
>
> [...]
> : I think that asking for sizeof(T&) in the first place is fairly bizarre,
> : unless it has something to do with templates, but even that's stretching
> : it. Asking sizeof(T&) to return the size of something that doesn't even
> : have a necessarily consistent size (a reference) is even more bizarre.
>
> What's bizarre about asking that sizeof return the number of bytes in
> its arguement, just like the C++ standard says it does?  A
> programmer's reasons for wanting to know are his/her own business, not
> that of the standards committee.  It is, however, the business of language
> designers and implementers not to mislead the programmer.

My understanding of a reference is that it is an alias for another
object.  In some situations the compiler may even be able to not
allocate any separate storage for a reference.  For instance, if we
have

int i = 1;
int &r = i;

in the same scope, the compiler can just "remember" that "r" is
referring to the same object as "i" and not allocate any separate
storage for "r".  In other cases, like reference parameters to
functions, the compiler might implement a reference as a pointer.  If
the standard required that sizeof(r) return a size distinct from the
size of the type that "r" is referring to, then sizeof(r) in the above
case would make no sense, since there could be no storage associated
with "r".  This is why it makes sense to me that

sizeof(r) == sizeof(i)

Adam
--
Adam P. Jenkins
mailto:ajenkins@cs.umass.edu
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: fjh@mundook.cs.mu.OZ.AU (Fergus Henderson)
Date: 1996/11/13
Raw View
ajenkins@cs.umass.edu (Adam P Jenkins) writes:

>My understanding of a reference is that it is an alias for another
>object.  In some situations the compiler may even be able to not
>allocate any separate storage for a reference.

Yes, but compilers can do lots of nifty optimizations to avoid
allocating storage.  What makes references so special?

>For instance, if we
>have
>
>int i = 1;
>int &r = i;
>
>in the same scope, the compiler can just "remember" that "r" is
>referring to the same object as "i" and not allocate any separate
>storage for "r".

But in this case, the compiler may also be able to optimize away the
storage for `i' too.

>If the standard required that sizeof(r) return a size distinct from the
>size of the type that "r" is referring to, then sizeof(r) in the above
>case would make no sense, since there could be no storage associated
>with "r".

By the same argument, sizeof(i) would make no sense either.

>This is why it makes sense to me that
>
>sizeof(r) == sizeof(i)

I think there are reasonable arguments why that should be true,
but I don't think the argument you gave above is one of them.

--
Fergus Henderson <fjh@cs.mu.oz.au>   |  "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh>   |  of excellence is a lethal habit"
PGP: finger fjh@128.250.37.3         |     -- the last words of T. S. Garp.
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Tom Payne <thp@cs.ucr.edu>
Date: 1996/11/13
Raw View
Adam P Jenkins <ajenkins@cs.umass.edu> wrote:
[...]
: My understanding of a reference is that it is an alias for another
: object.

The term "alias" is not defined in the standard, but most programmers
interpret it to mean an alternate name (i.e., use of an identifier).
Also, the standard explicitly says that a reference can be thought of
as a name.  My problem with that is that I can't find the identifier
whose use is begin returned in the function int& f(){return *new int;}.

I prefer, instead, to think of a reference as a place to store (the
result of) an lvalue, just as (other) objects are places to store
rvalues.

: In some situations the compiler may even be able to not
: allocate any separate storage for a reference.  For instance, if we
: have

: int i = 1;
: int &r = i;

: in the same scope, the compiler can just "remember" that "r" is
: referring to the same object as "i" and not allocate any separate
: storage for "r".

In this regard, r is acting link any (other) object that is not a
member of a POD class-or-struct object, whose address is not used, and
whose value can be determined at compile time.  AFIK, the storage for
any such object can be optimized away, by the as-if rule.

: In other cases, like reference parameters to
: functions, the compiler might implement a reference as a pointer.  If
: the standard required that sizeof(r) return a size distinct from the
: size of the type that "r" is referring to, then sizeof(r) in the above
: case would make no sense, since there could be no storage associated
: with "r".  This is why it makes sense to me that

: sizeof(r) == sizeof(i)

Agreed. There is no dispute about what the value of sizeof(r) should
be, since it is the fundamental semantics of references to refer all
operations to their referrents.  The dispute is about the value of
sizeof(int&) --- there is no semantic rule saying that type designator
int& denotes the type int.

Tom Payne
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: "Bill Wade" <bill.wade@stoner.com>
Date: 1996/11/13
Raw View
Chelly Green <chelly@eden.com> wrote in article <328757EF.6242@eden.com>...
> root@nntpa.cb.lucent.com wrote:

> What use would the storage required for a reference be?

It makes persistent store of objects containing references more convenient.

class foo
{
  int a;
  double b;
  bar* c;
  bar& d;

  void Read(persistentStore&);
  void Write(persistentStore&);
};

// Note: persistentStore::operator<<(bar*) maps the bar* to an int which is
// written and then writes *bar (if not already written)
//
// persistentStore::operator>>(bar*&) reverses the operation.

void foo::Write(persistentStore& ps)
{
  ps << a << b << c << &d;
}

struct barRef
{
  barRef(bar&b):x(b){}
  bar& x;
}

void foo::Read(persistentStore& ps)
{
  bar* dptr;
  ps >> a >> b >> c >> dptr;
  barRef y = *dptr;

  // There are a few things wrong with the next line but it would
  // be convenient if it worked.
  memcpy(this + offsetof(foo, d), &y+offsetof(barRef, x), sizeof(bar&));
}

About the best I can do to read references from persistent stores is

foo::foo(persistentStore& ps):
  a(ps.ReadInt()),
  b(ps.ReadDouble()),
  c(ps.ReadBarPtr()),
  d(*ps.ReadBarPtr())
{
}

which is considerably less type-safe ( b(ps.ReadInt()) won't give me any
compile error )
and means my Write() function had better write things in construction
order.

Note that even

  bar a;
  bar b;
  barRef x(a);
  barRef y(b);
  memcpy(&x, &y, sizeof(barRef));

is not certain to successfully copy a reference.  I don't believe
references have to abide by the "equal bit patterns implies equal value"
rule of objects.  For instance, I think it is perfectly legal for a
compiler to implement references in a manner similar to:

  class bar& // Compiler's implementation of a reference
  {
    private:
      const int offset;
    public:
      // Construct a reference
      bar&(bar& x):offset((char*)&x-(char*)this){}

      // Get the address of the thing we reference
      bar* operator&(){ return (bar*) ((char*)this + offset); }
    ...
  }

Taking a quick look at the April 95 draft (3.9 para 3) it looks like:
  T* x;
  T* y;
  memcpy(x,y,sizeof(T));
is only certain to copy values for scalars.  I would assume it is certain
to copy values for any POD object.  Am I missing something?
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: darin@goonsquad.spies.com (Darin Adler)
Date: 1996/11/14
Raw View
In article <m2zq0mppva.fsf@nscs46p16.remote.umass.edu>,
ajenkins@cs.umass.edu (Adam P Jenkins) wrote:
> [ ... ] For instance, if we have
>
> int i = 1;
> int &r = i;
>
> in the same scope, the compiler can just "remember" that "r" is
> referring to the same object as "i" and not allocate any separate
> storage for "r".  In other cases, like reference parameters to
> functions, the compiler might implement a reference as a pointer.  If
> the standard required that sizeof(r) return a size distinct from the
> size of the type that "r" is referring to, then sizeof(r) in the above
> case would make no sense, since there could be no storage associated
> with "r".  This is why it makes sense to me that
>
> sizeof(r) == sizeof(i)

I don't think this argument works.

Another poster pointed out that "i" could be optimized out too.  I think
that the same is true of a pointer "p".

int i = 1;
int *p = &i;

In your words: The compiler can just "remember" that "p" is referring to
the same object as "i" and not allocate any separate storage for "p".  In
other cases, like pointer parameters to functions, the compiler might
actually pass a pointer.

However, by examining this case we can see one difference between "r" and
"p".  It may be instructive to examine pointers to storage that can be used
with the result of "sizeof".  It's worth noting that "&r" will be a pointer
to the storage for "i" of type "int *" and that "&p" will be a pointer to
the storage for "p" with type "int **".  Thus, it's useful that sizeof(r)
gives sizeof(int) and sizeof(p) gives sizeof(int *).

So I agree with your conclusion.
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: "Bradd W. Szonye" <bradds@concentric.net>
Date: 1996/11/01
Raw View
I really don't understand all the fuss over sizeof(T&). The main _use_
of
sizeof is to determine the amount of storage the object takes for arrays
(or a comparable array of char or unsigned char) or copying. You can't
put
a reference in an array, and you can't copy one. Perhaps sizeof(T&)
should
be illegal, since it can't be put to any good use. The idea that it
should
return the size of something that you can't copy or put into any array
is
silly, however. It's not even useful for calculating the size of an
object
from its sub-objects (since that doesn't work anyway) or for calculating
offsetof().

Perhaps if someone explained _why_ you'd want to know sizeof(T&)--for
practical reasons--it would make more sense.

Tom Payne <thp@cs.ucr.edu> wrote in article
<55d9qr$coj@engnews1.Eng.Sun.COM>...
> In article <559r2e$kdb@netlab.cs.rpi.edu> Steve Clamage wrote:
> : On the other hand, it is a rare (probably non-existent) document which
> : cannot be interpreted in ways never dreamed of by the authors. In the
> : case of language standards, when there is a straightforward
> interpretation
> : and a possible strained or bizarre interpretation, it generally serves
> : no good purpose to insist on the bizarre.
>
> Apparently, "bizarreness" is in the mind of the beholder.

I think that asking for sizeof(T&) in the first place is fairly bizarre,
unless it has something to do with templates, but even that's stretching
it. Asking sizeof(T&) to return the size of something that doesn't even
have a necessarily consistent size (a reference) is even more bizarre.

> : In this case, there is no source
> : language mechanism to find out anything regarding the implementation
> : of references, and any use of a reference is always forwarded to the
> : referent.
>
> What the hell is the point of sizeof, if it isn't to find out things
> regarding the implementation of various entities?  And, why have two
> notations for finding the size of T and none for finding size of a
> reference to T.

It's for finding the sizes of things that you can then _do_ something
with
the size. You can't do anything useful with the size of a reference
(that
isn't undefined)--oh wait, Steve says this below.

> : Interpreting sizeof(T&) as anything other than sizeof(T)
> : would then, it seems to me, count as a bizarre interpretation. You
> can't
> : do anything useful with the putative size of the reference itself.
>
> In one of his columns, Pete Becker suggested that, if one needs to
> find the size of T&, one can declare a single-member struct and apply
> sizeof to it.  I find the need for such hacks (which are not
> guaranteed to work) to be "bizarre" in the extreme.  (Incidentally,
> the majority of C programmers with whom I've discussed the matter
> share this view.)

Note "if one needs to find the size of a reference"--again, why? The
"need"
for such hacks is bizarre because the need for the size of a reference
is
bizarre in the first place! Please don't make demands for the language
to
provide information that is programatically meaningless. Putting
constraints on the size of a reference is putting constraints on an
implementation for no good reason. An implementation should be able to
treat references as pointers when it's convenient and treat them
otherwise
when it's not.

> The problem is that the committee has tried to view references as
> mystical entities whose dynamically initialized value, unlike that of
> an int, can be remembered without using a segment of memory (object).

It's not mystical. It's intentionally vague so that an implementation
can
define references however it likes, whenever it likes, and doesn't need
to
be consistent about it. It's getting away from the notion of pointers
that
*must* be consistent (and for good reason). Don't pin down references so
much that there's only one reasonable interpretation.

> Rather, the mystical view of references is unsound --
> they have the same need for segments of
> storage as any constant int that is not a member of a POD object and
> whose address isn't used.

There's a big difference between a reference and an unstored int.
Objects
of constant integral type _can_ be a member of a POD object, _can_ be a
member of an array, and _can_ have its address taken. Therefore, you
need
to know the size an object of such a type occupies. There is no similar
need for the size of a reference.
--
Bradd W. Szonye
bradds@concentric.net
http://www.concentric.net/~bradds

      [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
      [ about comp.lang.c++.moderated. First time posters: do this! ]






Author: Tom Payne <thp@cs.ucr.edu>
Date: 1996/11/01
Raw View
[Note to moderator(s):  This thread is more appropriate to
comp.std.c++, so I'd like to cross post this response and direct
followups to that group (however that is done).  Thanks.]

In article <559r2e$kdb@netlab.cs.rpi.edu> Steve Clamage wrote:
: In article 4tn@netlab.cs.rpi.edu,  Tom Payne <thp@cs.ucr.edu> writes:
: >
: >We are in complete agreement that the parentheses in a "parenthesized
: >type" are only a matter of syntactic necessity and are of no semantic
: >significance.  We differ on whether the words
: >
: >  When applied to a reference, the result [of sizeof] is the size of
: >  the referenced type.  [5.3.3]
: >
: >define the result when sizeof is applied to a (parenthesized)
: >reference type, say T&.  My objection is that T& is a type, not a
: >reference, so this clause does not apply to it.

: It didn't occur to me that anyone could interpret that sentence that
: way. I suppose it wouldn't hurt to change the wording to something
like
: "When applied to a reference or to a reference type, the result ..."
: which is certainly what it is intended to mean.

: I'm sure the draft is filled with usages like "integer" or "pointer"
when
: "integer type" or "pointer type" would be more precise. Maybe someone
: would like to volunteer to find and report all such infelicities.

: On the other hand, it is a rare (probably non-existent) document which
: cannot be interpreted in ways never dreamed of by the authors. In the
: case of language standards, when there is a straightforward
interpretation
: and a possible strained or bizarre interpretation, it generally serves
: no good purpose to insist on the bizarre.

Apparently, "bizarreness" is in the mind of the beholder.

: In this case, there is no source
: language mechanism to find out anything regarding the implementation
: of references, and any use of a reference is always forwarded to the
: referent.

What the hell is the point of sizeof, if it isn't to find out things
regarding the implementation of various entities?  And, why have two
notations for finding the size of T and none for finding size of a
reference to T.

: Interpreting sizeof(T&) as anything other than sizeof(T)
: would then, it seems to me, count as a bizarre interpretation. You
can't
: do anything useful with the putative size of the reference itself.

In one of his columns, Pete Becker suggested that, if one needs to
find the size of T&, one can declare a single-member struct and apply
sizeof to it.  I find the need for such hacks (which are not
guaranteed to work) to be "bizarre" in the extreme.  (Incidentally,
the majority of C programmers with whom I've discussed the matter
share this view.)


The problem is that the committee has tried to view references as
mystical entities whose dynamically initialized value, unlike that of
an int, can be remembered without using a segment of memory (object).
The standard reflects this mysticism with statements such as

  Note: a reference can be thought of as a name of an object. [8.3.2]

which implies that reference-valued functions return uses of
identifiers.  Such absurdities are not merely flaws in the wording of
the standard.  Rather, the mystical view of references is unsound --
references aren't names, and they have the same need for segments of
storage as any constant int that is not a member of a POD object and
whose address isn't used.

The committee is, of course, free to play Humpty Dumpty and define
"object" to mean "an instance of a non-reference data type."  In that
case, however, the segment-of-storage definition should be dropped.

Tom Payne


      [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
      [ about comp.lang.c++.moderated. First time posters: do this! ]



[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Tom Payne <thp@cs.ucr.edu>
Date: 1996/11/06
Raw View
In comp.std.c++ Bradd W. Szonye <bradds@concentric.net> wrote:
:
: I really don't understand all the fuss over sizeof(T&). The main _use_ of
: sizeof is to determine the amount of storage the object takes for arrays
: (or a comparable array of char or unsigned char) or copying. You can't put
: a reference in an array, and you can't copy one. Perhaps sizeof(T&) should
: be illegal, since it can't be put to any good use. The idea that it should
: return the size of something that you can't copy or put into any array is
: silly, however. It's not even useful for calculating the size of an object
: from its sub-objects (since that doesn't work anyway) or for calculating
: offsetof().

: Perhaps if someone explained _why_ you'd want to know sizeof(T&)--for
: practical reasons--it would make more sense.

[...]
: I think that asking for sizeof(T&) in the first place is fairly bizarre,
: unless it has something to do with templates, but even that's stretching
: it. Asking sizeof(T&) to return the size of something that doesn't even
: have a necessarily consistent size (a reference) is even more bizarre.

What's bizarre about asking that sizeof return the number of bytes in
its arguement, just like the C++ standard says it does?  A
programmer's reasons for wanting to know are his/her own business, not
that of the standards committee.  It is, however, the business of language
designers and implementers not to mislead the programmer.

[...]
: > In one of his columns, Pete Becker suggested that, if one needs to
: > find the size of T&, one can declare a single-member struct and apply
: > sizeof to it.  I find the need for such hacks (which are not
: > guaranteed to work) to be "bizarre" in the extreme.  (Incidentally,
: > the majority of C programmers with whom I've discussed the matter
: > share this view.)

[...]
: The "need"
: for such hacks is bizarre because the need for the size of a reference is
: bizarre in the first place! Please don't make demands for the language to
: provide information that is programatically meaningless.

I'm simply noting that the common interpretation of sizeof(T&) is not
in keeping with a strict reading of the standard and/or the natural
behavior and intent of sizeof.  (Some have characterized that reading
as "bizarre.")  I recommend that the wording of the standard be
modified, with the addition of a single word, to reflect that common
interpretation, even though it's flawed (rather than break existing
implementations).

[...]
: > The problem is that the committee has tried to view references as
: > mystical entities whose dynamically initialized value, unlike that of
: > an int, can be remembered without using a segment of memory (object).

: It's not mystical. It's intentionally vague

Worse yet, as I've pointed out, it's misleading and inconsistent.

: so that an implementation can
: define references however it likes, whenever it likes, and doesn't need to
: be consistent about it. It's getting away from the notion of pointers that
: *must* be consistent (and for good reason). Don't pin down references so
: much that there's only one reasonable interpretation.

: Putting
: constraints on the size of a reference is putting constraints on an
: implementation for no good reason. An implementation should be able to
: treat references as pointers when it's convenient and treat them
: otherwise when it's not.

Although sizeof has a number of constraints, telling the truth is not
one of them.  FWIW, the implementer is free to implement in whatever
way is convenient and tell any lies he/she chooses about sizeof,
provided that sizeof(int) < sizeof(long) and a few other constraints
are satisfied.

: > Rather, the mystical view of references is unsound -- they have the
: > same need for segments of storage as any constant int that is not a
: > member of a POD object and whose address isn't used.

: There's a big difference between a reference and an unstored int.  Objects
: of constant integral type _can_ be a member of a POD object, _can_ be a
: member of an array, and _can_ have its address taken.

But, the point is that const ints to which none of those things happen
are still considered to be objects (segments of storage).  When you
say that something _can_ happen, you are simply saying that there is
another program in which it does happen.  But, whether or not an
entity is an object should not depend on what happens in other
programs.

Tom Payne
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: root@nntpa.cb.lucent.com
Date: 1996/11/08
Raw View
I would like to weigh in on the side of Tom on this issue.  We can say

 sizeof (type)
or
 sizeof expression

for all types except reference types.  Now, we can't have a
"reference-typed" expression by fundamental restriction of the
language; but why can't we have a "referenced-typed" type (if you
forgive my English) as an argument to sizeof?

For example (assume a machine with 2 byte integers and 4 byte addresses):

 int i, *ip=&i, &ir=i;
 size_t j;

 j = sizeof (int); // type; == 2
 j = sizeof i;  // expr; == 2
 j = sizeof *ip;  // expr; == 2
 j = sizeof ir;  // expr; == 2

 j = sizeof (int *); // type; == 4
 j = sizeof ip;  // expr; == 4
 j = sizeof &i;  // expr; == 4
 j = sizeof &ir;  // expr; == 4

 j = sizeof (&int); // type;

In my opinion, the last sizeof should evaluate to the storage size
of a reference when it is required to occupy storage, just like
sizeof behaves when given any other type as an argument.  The fact
that reference-typed expressions are not part of the language is
not a good reason for making an exception in the case of
reference types themselves as an argument to sizeof.

By the way, nothing says the size of a reference has to be the
same as the size of a pointer but a reasonable implementation
might make that choice.

Geno Rice
efrice@lucent.com

      [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
      [ about comp.lang.c++.moderated. First time posters: do this! ]
---
[ 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
]