Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Explanation for why sizeof doesn't work with new'd data

3 views
Skip to first unread message

Shane McDaniel

unread,
Nov 28, 2001, 1:30:13 PM11/28/01
to

can anyone provide an explanation why sizeof can't/doesn't report back the
size of data allocated with new?

ie

int *x = new int[40];

sizeof(x) is the size of the pointer not the 40 ints.

It seems that if you can delete new'd data you should be able do get the
size of new'd data.

An explanation or link to one would be appreciated.

-shane

Neil Butterworth

unread,
Nov 28, 2001, 1:40:51 PM11/28/01
to
"Shane McDaniel" <sha...@ll.mit.edu> wrote in message
news:Pine.WNT.4.33.01112...@bunnyhop.llan.ll.mit.edu...

>
> can anyone provide an explanation why sizeof can't/doesn't report back the
> size of data allocated with new?
>
> ie
>
> int *x = new int[40];
>
> sizeof(x) is the size of the pointer not the 40 ints.

Why should it return the size of the 40 ints? If it did, you would never be
able to find the size of the pointer!

> It seems that if you can delete new'd data you should be able do get the
> size of new'd data.

Maybe you should, but not using sizeof. An implementation could supply such
functionality, but standard C++ doesn't. In the case above you know the
number of ints is 40 because you created them in the first place.

> An explanation or link to one would be appreciated.

That's the way the language works

NeilB

Ron Natalie

unread,
Nov 28, 2001, 1:46:01 PM11/28/01
to

Shane McDaniel wrote:

> int *x = new int[40];
>
> sizeof(x) is the size of the pointer not the 40 ints.

because x is a pointer, it's size is not 40 ints, it's whatever
the pointer takes up.

There's no C++ syntax that says, give me the allocation that this
pointer points into (even the C++ iterators can't tell you want
container they are referring to).

>
> It seems that if you can delete new'd data you should be able do get the
> size of new'd data.
>

You could argue that, but the interface wouldn't be sizeof.

Default User

unread,
Nov 28, 2001, 3:14:48 PM11/28/01
to
Shane McDaniel wrote:
>
> can anyone provide an explanation why sizeof can't/doesn't report back the
> size of data allocated with new?

> It seems that if you can delete new'd data you should be able do get the


> size of new'd data.

Similar question was discussed on comp.lang.c recently. Requiring sizeof
to be able to return the size of dynamic memory would unreasonably
constrain implementors. Chris Torek (the BSD guy) had some great
examples of how that would cause problems for modern paging memory
systems. For instance, the system could allocate more memory than you
actually asked for. What would sizeof report? What you asked for? What
it gave you? What if later the system came back and took some away?

Brian Rodenborn

Ron Natalie

unread,
Nov 28, 2001, 4:56:03 PM11/28/01
to

Default User wrote:

>
> Similar question was discussed on comp.lang.c recently. Requiring sizeof
> to be able to return the size of dynamic memory would unreasonably
> constrain implementors. Chris Torek (the BSD guy) had some great
> examples of how that would cause problems for modern paging memory
> systems. For instance, the system could allocate more memory than you
> actually asked for. What would sizeof report? What you asked for? What
> it gave you? What if later the system came back and took some away?

You've lost me. sizeof isn't the right way. But even if there were a
how_big() function that did what the poster asked, how would that have any
effect on paging memory systems. I think you are confused about what
Chris was talking about.

how_big() would return how much YOU asked for. What the allocators do
internally is not an issue. What do you mean if the system came back
and took it away? The system damn well better not take away (virtual)
memory until free is called.

Default User

unread,
Nov 28, 2001, 6:26:56 PM11/28/01
to

Here's what he wrote, judge for yourself:


In article <3BFE7B5A...@veenhoven.com>
willem veenhoven <wil...@veenhoven.com> writes:
>However, I still think it is a good idea to add a feature for
>retrieving the size of an allocated block to the standard ...

This might constrain an implementation unreasonably (for some
definition of unreasonable :-) ).

For instance, suppose an implementor chooses to write a hybrid
malloc().

In this implementation, when you first ask for (say) 10000 bytes
you actually get 16384 bytes, and in general, most requests are
rounded up to whole pages.

Now, you might say: "OK, then getsize(ptrfrommalloc) should
just return the rounded-up-to-a-page size".

But wait! The system records not only that it handed out two
8192-byte pages (the 16384 bytes above), but *also* the fact that
you only *asked* for 10000 bytes. If you keep calling malloc, and
your memory usage starts to grow, the system goes back and *reclaims*
the extra bytes it handed out!

In other words, that 16384-byte block gets split into 10000 bytes
and 6384 "leftover" bytes that can be handed out to a subsequent
malloc for any value <= 6384.

So now, after getsize(ptrfrommalloc) returned 16384, it has to
change its mind and start returning 10000 instead.

Of course, you could say: "well then, if the system is going to
potentially shrink the area, it should just return 10000" -- but
now all getsize() is doing is returning the number you asked for,
which you could remember on your own.

In short, while this is not a completely bad idea, it has less
value than might first appear.

There is an equivalent, and perhaps more backwards-compatible,
alternative. Instead of asking for N bytes and seeing whether you
got M bytes (where M >= N), you might suggest that C0X have a
"size_t friendly_malloc_size(N)" function that returns an M, M>=N,
where M is "friendly" to the malloc() system. You can then do:

size_t need, askfor;
... // calculate value for need
askfor = friendly_malloc_size(need);
ptr = malloc(askfor);

The reason I say this is "perhaps more backwards-compatible" is
that it is trivial to define friendly_malloc_size() in your own
header based on whether __STDC__ is too small:

#if __STDC__ < 3
#define friendly_malloc_size(n) (n)
#endif

I have used exactly this kind of approach myself when allocating
bytes for a "string pool" (though I spelled it goodsize() in at
least that one instance). My goodsize() function was not just
defined as the identity function, but rather as a guess about the
underlying malloc() implementation; but the consequences if the
guess were wrong are minor anyway.

Karl Heinz Buchegger

unread,
Nov 29, 2001, 8:24:31 AM11/29/01
to

Shane McDaniel wrote:
>
> can anyone provide an explanation why sizeof can't/doesn't report back the
> size of data allocated with new?
>
> ie
>
> int *x = new int[40];
>
> sizeof(x) is the size of the pointer not the 40 ints.
>
> It seems that if you can delete new'd data you should be able do get the
> size of new'd data.
>

Why should you? You already know this size. It's the size you have asked for.

The key is: sizeof is evaluated at *compile time*. So you will always get
the size as the compiler sees it. Now it should be perfectly clear why
this can't work with dynamic allocations. They happen at *run time*.

--
Karl Heinz Buchegger
kbuc...@gascad.at

Jon Bills

unread,
Nov 29, 2001, 8:35:35 AM11/29/01
to
"Default User" <munged....@boeing.com> wrote in message
news:3C0545B8...@boeing.com...

> Shane McDaniel wrote:
> >
> > can anyone provide an explanation why sizeof can't/doesn't report back the
> > size of data allocated with new?
>
> > It seems that if you can delete new'd data you should be able do get the
> > size of new'd data.
>
> Similar question was discussed on comp.lang.c recently. Requiring sizeof
> to be able to return the size of dynamic memory would unreasonably
> constrain implementors.

[snip]
>
> Brian Rodenborn

I wouldn't know about that, but it would also constrain certain C++
metaprogramming techniques that rely on sizeof() being evaluated at compile
time. Check out /Modern C++ Design/ for details.

Jon.


--
Posted from [195.99.244.69]
via Mailgate.ORG Server - http://www.Mailgate.ORG

Shane McDaniel

unread,
Nov 29, 2001, 10:35:47 AM11/29/01
to

I would just like to clarify that I was using sizeof as an example, it's
not that I disagree with sizeof returning the size of the pointer and
not the DAM, but that I am curious from a technical stand point why
there is not a standard way of getting the size of the DAM through the
pointer, or why the designers thought it was too complicated/difficult
of a task to include in the standard. It seems that if delete can know
how much memory is proper to deallocate then you should be able to get
this size for other purposes too. The thread about rounding up to a
page size was interesting but like my above comment, if delete can know
the proper amount why not the programmer.

And as to why this is useful, if I have a bunch of array's of DAM it
get's cumbersome to keep a table of each allocation size, and kind of
makes it difficult to work with the DAM elegantly, whereas a getsize()
even at run-time would make things flow better.

-shane

Attila Feher

unread,
Nov 29, 2001, 10:40:29 AM11/29/01
to

The operating system does/language not know the size you have asked
for. It _only_ knows the size it allocated, which might easily be
rounded to the next 4 bytes boundary etc. So don't expect that form the
language. Why should I pay to store this info (when I do not need it)?
Because you need it?

I do not really see the issue here. Since you (I suppose) use a
properly encapsulated RAII concept, meaning a seperate class handling
those allocated things, why cannot you add a size member to it???

Attila

Shane McDaniel

unread,
Nov 29, 2001, 10:55:26 AM11/29/01
to

Again my question is if I can call delete and it delete's the proper
amount of memory regaurdless of byte boundaries, why can I not call
another function to simply retreive this value. The value is being stored
for delete to use so there is no need to do any extra storage. I'm not
trying to find some convoluted way to make my code nice, this question is
in no way related to ANY code I'm writting, it's a question for my
curiousity and no one seems to have a straight answer.

If I were simply writting a class and had a couple sets or DAM it would be
easy enough to keep track of it, I don't contest this, I don't care. What
I care about is why there is not a standard way to get the size of DAM
when there is a standard way to delete DAM.

My example was stated to show why I believe this to be useful
functionality. If you have a large number of DAM that perhaps is pointing
to other DAM and so on, it gets cumbersome to keep track of it all in
another structure. Yes you could argue that having an nth order DAM
allocation array is messy and there is probably a better way, but it's
just and example.

-shane

Ron Natalie

unread,
Nov 29, 2001, 11:42:40 AM11/29/01
to

Default User wrote:
>
> Ron Natalie wrote:
> >
> > Default User wrote:
> >
> > >
> > > Similar question was discussed on comp.lang.c recently. Requiring sizeof
> > > to be able to return the size of dynamic memory would unreasonably
> > > constrain implementors. Chris Torek (the BSD guy) had some great
> > > examples of how that would cause problems for modern paging memory
> > > systems. For instance, the system could allocate more memory than you
> > > actually asked for. What would sizeof report? What you asked for? What
> > > it gave you? What if later the system came back and took some away?
> >
> > You've lost me. sizeof isn't the right way. But even if there were a
> > how_big() function that did what the poster asked, how would that have any
> > effect on paging memory systems. I think you are confused about what
> > Chris was talking about.
> >
> > how_big() would return how much YOU asked for. What the allocators do
> > internally is not an issue. What do you mean if the system came back
> > and took it away? The system damn well better not take away (virtual)
> > memory until free is called.
>
> Here's what he wrote, judge for yourself:
>

The size how_big() returned is what you asked for. Just because it allocates
more, doesn't mean it "gave it to you" in any sense that malloc or new-allocators
work now. The fact that it might reclaim this 'extra" space doesn't mean anything
to the sane programmer as it was never yours to begin with.

Ron Natalie

unread,
Nov 29, 2001, 11:43:56 AM11/29/01
to


> And as to why this is useful, if I have a bunch of array's of DAM it
> get's cumbersome to keep a table of each allocation size, and kind of
> makes it difficult to work with the DAM elegantly, whereas a getsize()
> even at run-time would make things flow better.
>

In C++, there is nothing that prohibits you from writing your own allocators
and making a way to get at this information.

Karl Heinz Buchegger

unread,
Nov 29, 2001, 12:01:47 PM11/29/01
to

Shane McDaniel wrote:
>
>
> Again my question is if I can call delete and it delete's the proper
> amount of memory regaurdless of byte boundaries, why can I not call
> another function to simply retreive this value. The value is being stored
> for delete to use so there is no need to do any extra storage.

And here is your flaw: No it's not. At least not the way you think it is.
The value stored internally, is the amount of memory *actually allocated*,
which may be larger then the amount you requested.

> I'm not
> trying to find some convoluted way to make my code nice, this question is
> in no way related to ANY code I'm writting, it's a question for my
> curiousity and no one seems to have a straight answer.
>

The designers of C++ didn't think that you would need such a function,
basically because:
you already know the answer, because you used that value before, when
you allocated.

>
> My example was stated to show why I believe this to be useful
> functionality.

It is not as usefull as you think it is.

> If you have a large number of DAM that perhaps is pointing
> to other DAM and so on, it gets cumbersome to keep track of it all in
> another structure. Yes you could argue that having an nth order DAM
> allocation array is messy and there is probably a better way, but it's
> just and example.
>

It doesn't matter which example you can come up with, we can show you
always a much better way to do the same without having to ask
the memory manager for allocation sizes.

Default User

unread,
Nov 29, 2001, 1:17:21 PM11/29/01
to
Ron Natalie wrote:

> The size how_big() returned is what you asked for. Just because it allocates
> more, doesn't mean it "gave it to you" in any sense that malloc or new-allocators
> work now. The fact that it might reclaim this 'extra" space doesn't mean anything
> to the sane programmer as it was never yours to begin with.

I was going with Chris Torek's opinion on the matter. He knows a lot
more about implementation than I do.

Do you agree that I accurately reflected his words in my brief
summation? Or do you still maintain that I misunderstood what he said?

If the former, then we are done, because your argument is with Chris and
you can take it up with him. If the latter, then we can discuss where
you think I misinterpreted his words.


Brian Rodenborn

Ron Natalie

unread,
Nov 29, 2001, 2:13:43 PM11/29/01
to

Default User wrote:
>
> Ron Natalie wrote:
>
> > The size how_big() returned is what you asked for. Just because it allocates
> > more, doesn't mean it "gave it to you" in any sense that malloc or new-allocators
> > work now. The fact that it might reclaim this 'extra" space doesn't mean anything
> > to the sane programmer as it was never yours to begin with.
>
> I was going with Chris Torek's opinion on the matter. He knows a lot
> more about implementation than I do.
>
> Do you agree that I accurately reflected his words in my brief
> summation? Or do you still maintain that I misunderstood what he said?

I've known Chris for over 15 years now (back from the days he was ensconced
in the upper floors of the CS building at the University of Maryland). His
exposition is fine. The misinterpretation is your comments about the system
taking back malloc'd memory. It can't do that (and Chris didn't say that
it would). The whole digression he goes into is a situation where you would
use the "sizeof" function to determine the "extra" allocation and some how
use that. That had not been part of the discussion.

David Harmon

unread,
Nov 29, 2001, 2:24:30 PM11/29/01
to
On Thu, 29 Nov 2001 10:35:47 -0500 in comp.lang.c++,
Shane McDaniel <sha...@ll.mit.edu> wrote:

>not the DAM, but that I am curious from a technical stand point why
>there is not a standard way of getting the size of the DAM through the
>pointer, or why the designers thought it was too complicated/difficult
>of a task to include in the standard.

If you want to know WHY something in the C++ language is the way it is,
you may have better results asking on comp.std.c++, which is the newsgroup
for discussion of the activities of the C++ standardization committee.

My guess is that is that way because:
1. It always has been, and at some point somebody thought it was a good
idea to make "new" compatible with existing "malloc" which did not offer a
size query function.
2. To encourage good programming style. If you are going to be using
variable size arrays and need to ask the size, you should probably be
using std::vector.

Arnold Hendriks

unread,
Nov 29, 2001, 2:45:27 PM11/29/01
to

Suppose sizeof(x) would return 40. What do you suggest that
sizeof (x+1) should return?

--
Arnold Hendriks <a.hen...@b-lex.com>
B-Lex Information Technologies, http://www.b-lex.com/

Richard Norman

unread,
Nov 29, 2001, 3:49:43 PM11/29/01
to
On 29 Nov 2001 19:45:27 GMT, Arnold Hendriks <a.hen...@b-lex.com>
wrote:

>Shane McDaniel <sha...@ll.mit.edu> wrote:
>> can anyone provide an explanation why sizeof can't/doesn't report back the
>> size of data allocated with new?
>> ie
>> int *x = new int[40];
>> sizeof(x) is the size of the pointer not the 40 ints.
>
>> It seems that if you can delete new'd data you should be able do get the
>> size of new'd data.
>
>> An explanation or link to one would be appreciated.
>Suppose sizeof(x) would return 40. What do you suggest that
>sizeof (x+1) should return?

It is true that "someone" really does know that
int *x = new[40]
does hold 40 ints. The problem is that it is the
memory allocation system that knows, not the
compiler. At compilation time, all the compiler
knows is that x is a pointer to an int. And sizeof
will return the size of a pointer.

You can also think of it this way.


int *x = new int[40];

delete[] x;
x = MyFunctionThatReturnsSomethingFunny();

Now what is sizeof(x)? The compiler doesn't have
a clue.


i

Default User

unread,
Nov 29, 2001, 3:53:24 PM11/29/01
to
Ron Natalie wrote:

> I've known Chris for over 15 years now (back from the days he was ensconced
> in the upper floors of the CS building at the University of Maryland). His
> exposition is fine. The misinterpretation is your comments about the system
> taking back malloc'd memory. It can't do that (and Chris didn't say that
> it would). The whole digression he goes into is a situation where you would
> use the "sizeof" function to determine the "extra" allocation and some how
> use that. That had not been part of the discussion.

I'll intersperse my comments with his (his have the >'s)

Chris Torek (the BSD guy) had some great
examples of how that would cause problems for modern paging memory
systems. For instance, the system could allocate more memory than you
actually asked for.

>In this implementation, when you first ask for (say) 10000 bytes


>you actually get 16384 bytes, and in general, most requests are
>rounded up to whole pages.

What would sizeof report? What you asked for? What
it gave you?

>Now, you might say: "OK, then getsize(ptrfrommalloc) should
>just return the rounded-up-to-a-page size".But wait! The system

>records not only that it handed out two
>8192-byte pages (the 16384 bytes above), but *also* the fact that
>you only *asked* for 10000 bytes.

What if later the system came back and took some away?

>If you keep calling malloc, and

Micah Cowan

unread,
Nov 29, 2001, 6:19:26 PM11/29/01
to
"Jon Bills" <jon_...@hotmail.com> writes:

> "Default User" <munged....@boeing.com> wrote in message
> news:3C0545B8...@boeing.com...
>
> > Shane McDaniel wrote:
> > >
> > > can anyone provide an explanation why sizeof can't/doesn't report back the
> > > size of data allocated with new?
> >
> > > It seems that if you can delete new'd data you should be able do get the
> > > size of new'd data.
> >
> > Similar question was discussed on comp.lang.c recently. Requiring sizeof
> > to be able to return the size of dynamic memory would unreasonably
> > constrain implementors.
> [snip]
> >
> > Brian Rodenborn
>
> I wouldn't know about that, but it would also constrain certain C++
> metaprogramming techniques that rely on sizeof() being evaluated at compile
> time. Check out /Modern C++ Design/ for details.
>
> Jon.

In C, it can no longer be relied upon, in the case that the sizeof
expression is of variable-length array type. This is likely to carry
over to C++. Of course, this poses few problems to preexisting code,
since the preexisting code will naturally not be using variable-length
arrays; however, it could pose a potential problem for *templates*
which use sizeof on a variable-length array. I don't foresee this as
a very frequent problem, though...

Micah

Jon Bills

unread,
Nov 30, 2001, 4:56:08 AM11/30/01
to
Micah Cowan <mi...@cowanbox.com> wrote in message news:<yu8n115...@mcowan-linux.transmeta.com>...

I'm afraid I don't understand what you mean. Are you saying that we cannot
rely on sizeof() being evaluated at compile time in the future?

Jon.

Micah Cowan

unread,
Nov 30, 2001, 3:02:03 PM11/30/01
to
jon_...@hotmail.com (Jon Bills) writes:

> > > I wouldn't know about that, but it would also constrain certain C++
> > > metaprogramming techniques that rely on sizeof() being evaluated at compile
> > > time. Check out /Modern C++ Design/ for details.
> > >
> > > Jon.
> >
> > In C, it can no longer be relied upon, in the case that the sizeof
> > expression is of variable-length array type. This is likely to carry
> > over to C++. Of course, this poses few problems to preexisting code,
> > since the preexisting code will naturally not be using variable-length
> > arrays; however, it could pose a potential problem for *templates*
> > which use sizeof on a variable-length array. I don't foresee this as
> > a very frequent problem, though...
> >
> > Micah
>
> I'm afraid I don't understand what you mean. Are you saying that we cannot
> rely on sizeof() being evaluated at compile time in the future?
>
> Jon.

That's exactly what I'm saying. At the moment, this is only true in
C, and only true when the type of the operand is a variable-length
array (VLA), whose size can *only* be determined at runtime.

A VLA is something like:

void some_function(size_t my_size)
{
int vla[my_size];

printf("vla's size is %zu.\n", sizeof vla);
}

In the above example, vla is a variable-length array. Its size is
not determinable at compile-time, because its size is dependant on
the value of my_size each time the function is called. This is a new
feature to C, and most compilers don't yet support it, or support it
as an extension (in which case, the semantics probably differ
slightly). At the moment, there is only one C99 implementation in
existence. Others are getting there.

However, it seems very likely that this is a feature that C++ will
likely take on as well, in the next version of the standard.

HTH,
Micah

Steve Heller

unread,
Dec 3, 2001, 9:38:02 PM12/3/01
to
Micah Cowan <mi...@cowanbox.com> wrote:

So there really is a cost to allowing variable-length arrays. I
couldn't figure out any way that would be a drawback, but the
inability to use sizeof to figure out the type of a variable (as shown
in "Modern C++ Design" would clearly be a drawback. I guess every
language feature has some cost.

--
Steve Heller, WA0CPP
http://www.steveheller.com
Author of "Learning to Program in C++", Who's Afraid of C++?", "Who's Afraid of More C++?",
"Optimizing C++", and other books
Free online versions of "Who's Afraid of C++?" and "Optimizing C++" are now available
at http://www.steveheller.com/whos and http://www.steveheller.com/opt

Kaz Kylheku

unread,
Dec 4, 2001, 1:18:48 AM12/4/01
to
In article <ukdo0uck3ljt3gnk4...@4ax.com>, Steve Heller wrote:
> So there really is a cost to allowing variable-length arrays. I

Of course there is a cost. They are not magic. But you have to compare
that cost to writing your own dynamic array module, which will probably
be centered around some struct containing a pointer and a size field.
There is no reason to expect VLA's to have a cost that is any worse
than such a thing.

C99 variable length arrays are intended to be able to use automatic
memory. Dynamically allocating automatic memory is something that
can't be done portably in C (there is the alloca fucntion, but it is
nonstandard, and allocates memory that is associated with a function,
not with a statement block, so it has different storage duration semantics
from VLA's).

>couldn't figure out any way that would be a drawback, but the
>inability to use sizeof to figure out the type of a variable (as shown
>in "Modern C++ Design" would clearly be a drawback. I guess every
>language feature has some cost.

Not necessarily an increased run-time or code-size cost, however. What
cost does

while (test)
statement;

have compared to:

label0024:
if (!(test))
goto label0025;

statement;
goto label0024;

label0025: ;

?

There is a cost in that the compiler is larger for supporting the while
statement and perhaps a teensy bit slower.

There are some features that lead to efficient code *and* code clarity,
maintainability and programmer productivity all at the same time.
This happens, for instance, when the features generate code that is
semantically equivalent to what the programmer would repeatedly write
by hand if the features were not available. In a way, the programmer
is still writing the same program, but in a more condensed way
with less attention to some details. There is not much of a change
of abstraction in going from if/goto to while, or from, say,
explicitly calling functions to initialize or deinitialize an object to
having constructors.

Then some features are specifically intended to serve as optimization
hints. (E.g. inline functions).

Features that have a significant cost are usually those that bridge some
sizeable semantic gap between their expression and their implementation,
providing a large increase in the level of abstraction. The cost is
compounded when such high level abstractions are used to do low level
things. Flexibility is that which allows you to make big, useful changes
in behavior using small changes in the expression of the program,
allowing that program to have a latent ability to easily become a
different program in the future. When you are getting flexibility, rather
than just a more compact notation or the elimination of some repetitive
bookkeeping work, that's usually when there is some kind of cost.
Also, the machine may be writing code for you whose equivalent you would
not write by hand, or perhaps even could not.

Adin Hunter Baber

unread,
Dec 4, 2001, 2:23:50 AM12/4/01
to
In article <ukdo0uck3ljt3gnk4...@4ax.com>,
Steve Heller <st...@steveheller.com> wrote:

I personally don't see any reason for the standards body to modify
sizeof. After all the above code could easily be rewritten as:

void some_function(size_t my_size)
{
int vla[my_size];

int totalSize = sizeof(int) * mySize;
printf("vla's size is %zu.\n", totalSize);
}

Why should sizeof be modified when this will do?

--
Adin Hunter Baber
"Death is lighter than a feather, Duty heavier than a mountain"
"...nevertheless, they fought on even though their homes were piles of ashes,
even though they knew they could not win they still fought on,..."

Ben Pfaff

unread,
Dec 4, 2001, 2:31:23 AM12/4/01
to
Adin Hunter Baber <mjolnir...@soltec.net> writes:

> I personally don't see any reason for the standards body to modify
> sizeof. After all the above code could easily be rewritten as:
>
> void some_function(size_t my_size)
> {
> int vla[my_size];
> int totalSize = sizeof(int) * mySize;
> printf("vla's size is %zu.\n", totalSize);
> }
>
> Why should sizeof be modified when this will do?

The C99 standard committee had (at least) two options with sizeof
and VLAs:

* They could create an inconsistency such that sizeof
applied to a VLA returned a misleading result (e.g.,
size of an element) or such that it was completely
disallowed.

* They could create an inconsistency such that sizeof
applied to a VLA was correct, but was not a constant
expression.

They obviously chose the second option. The Rationale indicates
that this was a conscious choice for consistency, in fact:

With the addition of variable length arrays (6.7.5.2) in
C9X, the sizeof operator is a constant expression only if
the type of the operand is not a variable length array
type. However, the notion of "size" is consistently
maintained for important operations such as pointer
increment, subscripting, and pointer difference. That is,
it is still possible to determine the number of elements in
a variable length array with

sizeof(vla) / sizeof(vla[0])

Finally, sizeof can still be used in an argument to the
malloc function.

Steve Heller

unread,
Dec 5, 2001, 10:46:30 AM12/5/01
to
k...@ashi.footprints.net (Kaz Kylheku) wrote:

>In article <ukdo0uck3ljt3gnk4...@4ax.com>, Steve Heller wrote:
>> So there really is a cost to allowing variable-length arrays. I
>
>Of course there is a cost. They are not magic. But you have to compare
>that cost to writing your own dynamic array module, which will probably
>be centered around some struct containing a pointer and a size field.
>There is no reason to expect VLA's to have a cost that is any worse
>than such a thing.

No, what I meant was not run-time cost, but the inability to use
sizeof to determine type at compile time, as illustrated in "Modern
C++ Design".

Kaz Kylheku

unread,
Dec 5, 2001, 1:12:26 PM12/5/01
to
In article <j9gs0uoq1ijevg6a4...@4ax.com>, Steve Heller wrote:
>k...@ashi.footprints.net (Kaz Kylheku) wrote:
>
>>In article <ukdo0uck3ljt3gnk4...@4ax.com>, Steve Heller wrote:
>>> So there really is a cost to allowing variable-length arrays. I
>>
>>Of course there is a cost. They are not magic. But you have to compare
>>that cost to writing your own dynamic array module, which will probably
>>be centered around some struct containing a pointer and a size field.
>>There is no reason to expect VLA's to have a cost that is any worse
>>than such a thing.
>
> No, what I meant was not run-time cost, but the inability to use
>sizeof to determine type at compile time, as illustrated in "Modern
>C++ Design".

sizeof determines size, not type.

Micah Cowan

unread,
Dec 5, 2001, 2:30:38 PM12/5/01
to
Steve Heller <st...@steveheller.com> writes:

> k...@ashi.footprints.net (Kaz Kylheku) wrote:
>
> >In article <ukdo0uck3ljt3gnk4...@4ax.com>, Steve Heller wrote:
> >> So there really is a cost to allowing variable-length arrays. I
> >
> >Of course there is a cost. They are not magic. But you have to compare
> >that cost to writing your own dynamic array module, which will probably
> >be centered around some struct containing a pointer and a size field.
> >There is no reason to expect VLA's to have a cost that is any worse
> >than such a thing.
>
> No, what I meant was not run-time cost, but the inability to use
> sizeof to determine type at compile time, as illustrated in "Modern
> C++ Design".

He never said run-time cost, and a cursory examination of his post
shows that he was clearly not talking about it, either. His point is
that all new language features come at some cost, even if its as
trivial a cost as a slightly more complicated compiler.

I agree that this was perhaps a more grave cost than you might like,
however, as I think Kaz successfully illustrated, the alternative is
less appealing. At any rate, it has very little chance of affecting
your code, with the exception I already noted of passing a VLA as a
type-param to a template. Other than that, I can't really think of
anything. Anyway, it's conceivable that the C++ folks can even solve
it so that the template problem isn't even an issue. In the meantime,
VLAs haven't arrived in C++ - and even when they do (assuming they
do), they're not likely to be used terribly often, since C++'s vectors
are probably better for most uses.

Micah

Steve Heller

unread,
Dec 5, 2001, 10:26:47 PM12/5/01
to
k...@ashi.footprints.net (Kaz Kylheku) wrote:

sizeof can be used to tell whether one type can be converted into
another, and whether an object is of some specific type. See "Modern
C++ Design" for details.

Steve Heller

unread,
Dec 5, 2001, 10:30:27 PM12/5/01
to
Micah Cowan <mi...@cowanbox.com> wrote:

>Steve Heller <st...@steveheller.com> writes:
>
>> k...@ashi.footprints.net (Kaz Kylheku) wrote:
>>
>> >In article <ukdo0uck3ljt3gnk4...@4ax.com>, Steve Heller wrote:
>> >> So there really is a cost to allowing variable-length arrays. I
>> >
>> >Of course there is a cost. They are not magic. But you have to compare
>> >that cost to writing your own dynamic array module, which will probably
>> >be centered around some struct containing a pointer and a size field.
>> >There is no reason to expect VLA's to have a cost that is any worse
>> >than such a thing.
>>
>> No, what I meant was not run-time cost, but the inability to use
>> sizeof to determine type at compile time, as illustrated in "Modern
>> C++ Design".
>
>He never said run-time cost, and a cursory examination of his post
>shows that he was clearly not talking about it, either. His point is
>that all new language features come at some cost, even if its as
>trivial a cost as a slightly more complicated compiler.

I don't think it's that obvious that he wasn't talking about
run-time cost, but it's not worth arguing about, so I'll concede.

>I agree that this was perhaps a more grave cost than you might like,
>however, as I think Kaz successfully illustrated, the alternative is
>less appealing.

It may very well be worth the cost; I was merely mentioning the fact
that I hadn't considered that it would affect any programs or
programming idioms negatively.

> At any rate, it has very little chance of affecting
>your code, with the exception I already noted of passing a VLA as a
>type-param to a template. Other than that, I can't really think of
>anything.

Or any other time you need to be able to determine the type of
something at compile time, if there are any other times.

> Anyway, it's conceivable that the C++ folks can even solve
>it so that the template problem isn't even an issue. In the meantime,
>VLAs haven't arrived in C++ - and even when they do (assuming they
>do), they're not likely to be used terribly often, since C++'s vectors
>are probably better for most uses.

I agree, although I could have used them on a couple of occasions.

Adam Petersen

unread,
Dec 6, 2001, 3:30:11 AM12/6/01
to

"Steve Heller" <st...@steveheller.com> wrote

> k...@ashi.footprints.net (Kaz Kylheku) wrote:
> >In article <j9gs0uoq1ijevg6a4...@4ax.com>, Steve Heller wrote:

<snip>

> >sizeof determines size, not type.
>
> sizeof can be used to tell whether one type can be converted into
> another, and whether an object is of some specific type. See "Modern
> C++ Design" for details.

And sizeof is doing this by determining the *size* of the objects.
The comment Kaz made is of course correct; sizeof alone is not able to
determine the type of an object.

/Adam


Micah Cowan

unread,
Dec 6, 2001, 4:50:59 PM12/6/01
to
Steve Heller <st...@steveheller.com> writes:

> k...@ashi.footprints.net (Kaz Kylheku) wrote:
>
> >In article <j9gs0uoq1ijevg6a4...@4ax.com>, Steve Heller wrote:
> >>k...@ashi.footprints.net (Kaz Kylheku) wrote:
> >>
> >>>In article <ukdo0uck3ljt3gnk4...@4ax.com>, Steve Heller wrote:
> >>>> So there really is a cost to allowing variable-length arrays. I
> >>>
> >>>Of course there is a cost. They are not magic. But you have to compare
> >>>that cost to writing your own dynamic array module, which will probably
> >>>be centered around some struct containing a pointer and a size field.
> >>>There is no reason to expect VLA's to have a cost that is any worse
> >>>than such a thing.
> >>
> >> No, what I meant was not run-time cost, but the inability to use
> >>sizeof to determine type at compile time, as illustrated in "Modern
> >>C++ Design".
> >
> >sizeof determines size, not type.
>
> sizeof can be used to tell whether one type can be converted into
> another, and whether an object is of some specific type. See "Modern
> C++ Design" for details.

sizeof certainly cannot be used to determine "whether an object is of
some specific type". The best it can do is tell if it's *probably* of
some specific type. Nor can sizeof be used to determine
convertability. That's what dynamic_cast<>() is for, for crying out
loud! If you can refute me with a quote from your "Modern C++
Design", that is additionally backed up by the Standard (only
authority here), I'd be very interested. I have a feeling its the
sort of book I'd be avoiding like the plague, if within its covers
such nonsense as this may be found.

sizeof is only useful for determining an object's size in bytes. An
object's size in bytes indicates nothing about what it could be, only
(sometimes) what it can *not* be. If sizeof some object produces '1',
what do you know about it? Could be a char, short, int, long - who
knows? If sizeof foo == sizeof (long), do we know that foo must
therefore be a long? We can't even determine that it's larger than int!

Micah

Steve Heller

unread,
Dec 6, 2001, 11:20:31 PM12/6/01
to
"Adam Petersen" <adam.p...@sea.ericsson.se> wrote:

Yes, of course that is true. But if sizeof cannot be used in the
idiom in "Modern C++ design" because it can't tell the size of a
variable-size array, then we wouldn't be able to use that idiom in
that case.

Steve Heller

unread,
Dec 6, 2001, 11:22:18 PM12/6/01
to
Micah Cowan <mi...@cowanbox.com> wrote:

Please argue with the author, not me.

Steve Heller

unread,
Dec 6, 2001, 11:53:41 PM12/6/01
to
Micah Cowan <mi...@cowanbox.com> wrote:

> If you can refute me with a quote from your "Modern C++
>Design", that is additionally backed up by the Standard (only
>authority here), I'd be very interested. I have a feeling its the
>sort of book I'd be avoiding like the plague, if within its covers
>such nonsense as this may be found.

You should definitely let Bjarne know about this, as the referenced
book is in his "C++ in Depth Series". I'm sure he'll be glad to hear
about its defects from someone who hasn't read it.

Kaz Kylheku

unread,
Dec 7, 2001, 1:47:47 AM12/7/01
to
In article <hapt0u8klp6qseutj...@4ax.com>, Steve Heller wrote:
>k...@ashi.footprints.net (Kaz Kylheku) wrote:
>
>>In article <j9gs0uoq1ijevg6a4...@4ax.com>, Steve Heller wrote:
>>>k...@ashi.footprints.net (Kaz Kylheku) wrote:
>>>
>>>>In article <ukdo0uck3ljt3gnk4...@4ax.com>, Steve Heller wrote:
>>>>> So there really is a cost to allowing variable-length arrays. I
>>>>
>>>>Of course there is a cost. They are not magic. But you have to compare
>>>>that cost to writing your own dynamic array module, which will probably
>>>>be centered around some struct containing a pointer and a size field.
>>>>There is no reason to expect VLA's to have a cost that is any worse
>>>>than such a thing.
>>>
>>> No, what I meant was not run-time cost, but the inability to use
>>>sizeof to determine type at compile time, as illustrated in "Modern
>>>C++ Design".
>>
>>sizeof determines size, not type.
>
> sizeof can be used to tell whether one type can be converted into
>another, and whether an object is of some specific type. See "Modern
>C++ Design" for details.

Are you sure you are not confusing sizeof and typeid?

Types do not have unique sizes. For example
sizeof (int) == sizeof (float) == sizeof (char *)
is not uncommon.

Why or how would you use sizeof to tell whether an expression has
some specific type? And why would you *not* use typeid to do this?

Can you cite an example, or do I have to buy your book?

Kaz Kylheku

unread,
Dec 7, 2001, 1:48:45 AM12/7/01
to
In article <hapt0u8klp6qseutj...@4ax.com>, Steve Heller wrote:
>k...@ashi.footprints.net (Kaz Kylheku) wrote:
>
>>In article <j9gs0uoq1ijevg6a4...@4ax.com>, Steve Heller wrote:
>>>k...@ashi.footprints.net (Kaz Kylheku) wrote:
>>>
>>>>In article <ukdo0uck3ljt3gnk4...@4ax.com>, Steve Heller wrote:
>>>>> So there really is a cost to allowing variable-length arrays. I
>>>>
>>>>Of course there is a cost. They are not magic. But you have to compare
>>>>that cost to writing your own dynamic array module, which will probably
>>>>be centered around some struct containing a pointer and a size field.
>>>>There is no reason to expect VLA's to have a cost that is any worse
>>>>than such a thing.
>>>
>>> No, what I meant was not run-time cost, but the inability to use
>>>sizeof to determine type at compile time, as illustrated in "Modern
>>>C++ Design".
>>
>>sizeof determines size, not type.
>
> sizeof can be used to tell whether one type can be converted into
>another, and whether an object is of some specific type. See "Modern
>C++ Design" for details.

Are you sure you are not confusing sizeof and typeid?

Types do not have unique sizes. For example
sizeof (int) == sizeof (float) == sizeof (char *)
is not uncommon.

Why or how would you use sizeof to tell whether an expression has
some specific type? And why would you *not* use typeid to do this?

Can you cite a small example? I do not have this book.

Adam Petersen

unread,
Dec 7, 2001, 2:39:59 AM12/7/01
to

"Kaz Kylheku" <k...@ashi.footprints.net> wrote in message
news:hDZP7.30489$nm3.1...@news1.rdc1.bc.home.com...

> In article <hapt0u8klp6qseutj...@4ax.com>, Steve Heller wrote:
> >k...@ashi.footprints.net (Kaz Kylheku) wrote:
> >
> >>In article <j9gs0uoq1ijevg6a4...@4ax.com>, Steve Heller wrote:
> >>>k...@ashi.footprints.net (Kaz Kylheku) wrote:
> >>>
> >>>>In article <ukdo0uck3ljt3gnk4...@4ax.com>, Steve Heller wrote:

<snip>

> >>sizeof determines size, not type.
> >
> > sizeof can be used to tell whether one type can be converted into
> >another, and whether an object is of some specific type. See "Modern
> >C++ Design" for details.
>
> Are you sure you are not confusing sizeof and typeid?

The problem is that Steve is confusing sizeof as part of an idiom and
sizeof alone. Alexandrescu shows an excellent technique for detecting
*convertibility* at *compile time*. The core of his idea is something like:

typedef char Small;
class Big { char dummy[2]; }
Small Test(U);
Big Test(...);
const bool conv = sizeof(Test(T())) == sizeof(Small);

There are more participants here than just a naked sizeof...

> Types do not have unique sizes. For example
> sizeof (int) == sizeof (float) == sizeof (char *)
> is not uncommon.
>
> Why or how would you use sizeof to tell whether an expression has
> some specific type? And why would you *not* use typeid to do this?

Steve is wrong, when he writes that sizeof can be used to
detect "whether an object is of some specific type". It is indeed
possible already at compile time, where typeid isn't of much use:-),
but not with sizeof (Alexandrescu uses typelists and template specializations).

/Adam


Steve Heller

unread,
Dec 7, 2001, 2:44:04 AM12/7/01
to
k...@ashi.footprints.net (Kaz Kylheku) wrote:

It's not my book, although I wish it were. In any event, you should
get it. Here is the code from the book that will tell you the
relationship between two types. Sorry for the size, but this is the
header file that does the trick. Unfortunately, you need a fairly
compliant compiler to compile it:

Steve Heller

unread,
Dec 7, 2001, 2:47:56 AM12/7/01
to
k...@ashi.footprints.net (Kaz Kylheku) wrote:

It's not my book, although I wish it were. Here is the code from the


book that will tell you the relationship between two types. Sorry for
the size, but this is the header file that does the trick.

Unfortunately, you need a fairly compliant compiler to compile it, and
I don't have one that will do the job on my machine, so I can't tell
you that I've run it successfully.

////////////////////////////////////////////////////////////////////////////////
// The Loki Library
// Copyright (c) 2001 by Andrei Alexandrescu
// This code accompanies the book:
// Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and
Design
// Patterns Applied". Copyright (c) 2001. Addison-Wesley.
// Permission to use, copy, modify, distribute and sell this software
for any
// purpose is hereby granted without fee, provided that the above
copyright
// notice appear in all copies and that both that copyright notice
and this
// permission notice appear in supporting documentation.
// The author or Addison-Welsey Longman make no representations about
the
// suitability of this software for any purpose. It is provided
"as is"
// without express or implied warranty.
////////////////////////////////////////////////////////////////////////////////

// Last update: June 20, 2001

#ifndef TYPEMANIP_INC_
#define TYPEMANIP_INC_

namespace Loki
{
////////////////////////////////////////////////////////////////////////////////
// class template Int2Type
// Converts each integral constant into a unique type
// Invocation: Int2Type<v> where v is a compile-time constant integral
// Defines 'value', an enum that evaluates to v
////////////////////////////////////////////////////////////////////////////////

template <int v>
struct Int2Type
{
enum { value = v };
};

////////////////////////////////////////////////////////////////////////////////
// class template Type2Type
// Converts each type into a unique, insipid type
// Invocation Type2Type<T> where T is a type
// Defines the type OriginalType which maps back to T
////////////////////////////////////////////////////////////////////////////////

template <typename T>
struct Type2Type
{
typedef T OriginalType;
};

////////////////////////////////////////////////////////////////////////////////
// class template Select
// Selects one of two types based upon a boolean constant
// Invocation: Select<flag, T, U>::Result
// where:
// flag is a compile-time boolean constant
// T and U are types
// Result evaluates to T if flag is true, and to U otherwise.
////////////////////////////////////////////////////////////////////////////////

template <bool flag, typename T, typename U>
struct Select
{
typedef T Result;
};
template <typename T, typename U>
struct Select<false, T, U>
{
typedef U Result;
};

////////////////////////////////////////////////////////////////////////////////
// Helper types Small and Big - guarantee that sizeof(Small) <
sizeof(Big)
////////////////////////////////////////////////////////////////////////////////

namespace Private
{
template <class T, class U>
struct ConversionHelper
{
typedef char Small;
struct Big { char dummy[2]; };
static Big Test(...);
static Small Test(U);
static T MakeT();
};
}

////////////////////////////////////////////////////////////////////////////////
// class template Conversion
// Figures out the conversion relationships between two types
// Invocations (T and U are types):
// a) Conversion<T, U>::exists
// returns (at compile time) true if there is an implicit conversion
from T
// to U (example: Derived to Base)
// b) Conversion<T, U>::exists2Way
// returns (at compile time) true if there are both conversions from T
// to U and from U to T (example: int to char and back)
// c) Conversion<T, U>::sameType
// returns (at compile time) true if T and U represent the same type
//
// Caveat: might not work if T and U are in a private inheritance
hierarchy.
////////////////////////////////////////////////////////////////////////////////

template <class T, class U>
struct Conversion
{
typedef Private::ConversionHelper<T, U> H;
#ifndef __MWERKS__
enum { exists = sizeof(typename H::Small) ==
sizeof(H::Test(H::MakeT())) };
#else
enum { exists = false };
#endif
enum { exists2Way = exists && Conversion<U, T>::exists };
enum { sameType = false };
};

template <class T>
struct Conversion<T, T>
{
enum { exists = 1, exists2Way = 1,sameType = 1 };
};

template <class T>
struct Conversion<void, T>
{
enum { exists = 1, exists2Way = 0,sameType = 0 };
};

template <class T>
struct Conversion<T, void>
{
enum { exists = 1, exists2Way = 0,sameType = 0 };
};

template <>
class Conversion<void, void>
{
public:
enum { exists = 1, exists2Way = 1,sameType = 1 };
};
}

////////////////////////////////////////////////////////////////////////////////
// macro SUPERSUBCLASS
// Invocation: SUPERSUBCLASS(B, D) where B and D are types.
// Returns true if B is a public base of D, or if B and D are aliases
of the
// same type.
//
// Caveat: might not work if T and U are in a private inheritance
hierarchy.
////////////////////////////////////////////////////////////////////////////////

#define SUPERSUBCLASS(T, U) \
(::Loki::Conversion<const U*, const T*>::exists && \
!::Loki::Conversion<const T*, const void*>::sameType)

////////////////////////////////////////////////////////////////////////////////
// macro SUPERSUBCLASS
// Invocation: SUPERSUBCLASS(B, D) where B and D are types.
// Returns true if B is a public base of D.
//
// Caveat: might not work if T and U are in a private inheritance
hierarchy.
////////////////////////////////////////////////////////////////////////////////

#define SUPERSUBCLASS_STRICT(T, U) \
(SUPERSUBCLASS(T, U) && \
!::Loki::Conversion<const T, const U>::sameType)

////////////////////////////////////////////////////////////////////////////////
// Change log:
// June 20, 2001: ported by Nick Thurn to gcc 2.95.3. Kudos, Nick!!!
////////////////////////////////////////////////////////////////////////////////

#endif // TYPEMANIP_INC_


//test code to illustrate use------------------
#include <iostream>

using namespace std;

class A
{
};

class B : public A
{
};

int main()
{

cout << "is B a subclass of A? : " << SUPERSUBCLASS(A,B) << endl;

Jon Bills

unread,
Dec 7, 2001, 4:45:30 AM12/7/01
to
Micah Cowan <mi...@cowanbox.com> wrote in message news:<yu87ks0...@mcowan-linux.transmeta.com>...
[snip]

>
> sizeof certainly cannot be used to determine "whether an object is of
> some specific type". The best it can do is tell if it's *probably* of
> some specific type. Nor can sizeof be used to determine
> convertability. That's what dynamic_cast<>() is for, for crying out
> loud! If you can refute me with a quote from your "Modern C++
> Design", that is additionally backed up by the Standard (only
> authority here), I'd be very interested. I have a feeling its the
> sort of book I'd be avoiding like the plague, if within its covers
> such nonsense as this may be found.
>
> sizeof is only useful for determining an object's size in bytes. An
> object's size in bytes indicates nothing about what it could be, only
> (sometimes) what it can *not* be. If sizeof some object produces '1',
> what do you know about it? Could be a char, short, int, long - who
> knows? If sizeof foo == sizeof (long), do we know that foo must
> therefore be a long? We can't even determine that it's larger than int!
>
> Micah

The point is that some of Alexandrescu's idioms rely on sizeof() being
determinable at compile time. dynamic_cast<>() would not fulfil the
requirements of those idioms. I think you'll find that the idioms rely
on Standard behaviour of C++, and there is nothing wrong with
Alexandrescu's
understanding of the Standard. I believe Steve's posted the code
somewhere
else in this thread, so I won't repeat it here.

This leads to the issue that there is / will be a significant number
of apps built around these idioms and changing sizeof() to be
evaluated /at runtime only/ will cause those apps to break.
Personally, I don't see a requirement for
sizeof() to not be evaluated at compile-time. If VLAs are added to
C++, surely
it's possible to overload sizeof() to evaluate only those at runtime?
Adin
Hunter Baber and Ben Pfaff both posted details of how sizeof()'s
result can
continue to be a compile-time constant for existing operands.

Jon.

Steve Heller

unread,
Dec 7, 2001, 7:25:18 AM12/7/01
to
"Adam Petersen" <adam.p...@sea.ericsson.se> wrote:

>
>"Kaz Kylheku" <k...@ashi.footprints.net> wrote in message
>news:hDZP7.30489$nm3.1...@news1.rdc1.bc.home.com...
>> In article <hapt0u8klp6qseutj...@4ax.com>, Steve Heller wrote:
>> >k...@ashi.footprints.net (Kaz Kylheku) wrote:
>> >
>> >>In article <j9gs0uoq1ijevg6a4...@4ax.com>, Steve Heller wrote:
>> >>>k...@ashi.footprints.net (Kaz Kylheku) wrote:
>> >>>
>> >>>>In article <ukdo0uck3ljt3gnk4...@4ax.com>, Steve Heller wrote:
>
><snip>
>
>> >>sizeof determines size, not type.
>> >
>> > sizeof can be used to tell whether one type can be converted into
>> >another, and whether an object is of some specific type. See "Modern
>> >C++ Design" for details.
>>
>> Are you sure you are not confusing sizeof and typeid?
>
>The problem is that Steve is confusing sizeof as part of an idiom and
>sizeof alone. Alexandrescu shows an excellent technique for detecting
>*convertibility* at *compile time*. The core of his idea is something like:

I am confusing nothing. What I originally said was that sizeof was
needed in this idiom. And it is.

>
>typedef char Small;
>class Big { char dummy[2]; }
>Small Test(U);
>Big Test(...);
>const bool conv = sizeof(Test(T())) == sizeof(Small);
>
>There are more participants here than just a naked sizeof...
>
>> Types do not have unique sizes. For example
>> sizeof (int) == sizeof (float) == sizeof (char *)
>> is not uncommon.
>>
>> Why or how would you use sizeof to tell whether an expression has
>> some specific type? And why would you *not* use typeid to do this?
>
>Steve is wrong, when he writes that sizeof can be used to
>detect "whether an object is of some specific type". It is indeed
>possible already at compile time, where typeid isn't of much use:-),
>but not with sizeof (Alexandrescu uses typelists and template specializations).

I said it was necessary, not that it was sufficient.

Steve Heller

unread,
Dec 7, 2001, 7:27:23 AM12/7/01
to
jon_...@hotmail.com (Jon Bills) wrote:

>The point is that some of Alexandrescu's idioms rely on sizeof() being
>determinable at compile time. dynamic_cast<>() would not fulfil the
>requirements of those idioms. I think you'll find that the idioms rely
>on Standard behaviour of C++, and there is nothing wrong with
>Alexandrescu's
>understanding of the Standard. I believe Steve's posted the code
>somewhere
>else in this thread, so I won't repeat it here.
>
>This leads to the issue that there is / will be a significant number
>of apps built around these idioms and changing sizeof() to be
>evaluated /at runtime only/ will cause those apps to break.
>Personally, I don't see a requirement for
>sizeof() to not be evaluated at compile-time. If VLAs are added to
>C++, surely
>it's possible to overload sizeof() to evaluate only those at runtime?
>Adin
>Hunter Baber and Ben Pfaff both posted details of how sizeof()'s
>result can
>continue to be a compile-time constant for existing operands.

Thank you. Finally someone understands what I was saying. For a
moment, I thought it was me.

Jon Bills

unread,
Dec 7, 2001, 8:06:58 AM12/7/01
to
"Steve Heller" <st...@steveheller.com> wrote in message
news:8cd11usvuod2tan80...@4ax.com...

[snip]

> Thank you. Finally someone understands what I was saying. For a
> moment, I thought it was me.

It would seem that your statement "but the inability to use sizeof to
figure out the type of a variable [...] would clearly be a drawback" has
been bent out of shape. It would very much be a drawback if this goes on
to break legacy code. Not that I'm suggesting Alexandrescu's idioms appear
in legacy code... yet. I'm sure the ISO committee consider back-compatibility
issues.

Jon.


--
Posted from [195.99.244.69]
via Mailgate.ORG Server - http://www.Mailgate.ORG

Steve Heller

unread,
Dec 7, 2001, 11:55:21 AM12/7/01
to
"Jon Bills" <jon_...@hotmail.com> wrote:

>"Steve Heller" <st...@steveheller.com> wrote in message
>news:8cd11usvuod2tan80...@4ax.com...
>
>[snip]
>
>> Thank you. Finally someone understands what I was saying. For a
>> moment, I thought it was me.
>
>It would seem that your statement "but the inability to use sizeof to
>figure out the type of a variable [...] would clearly be a drawback" has
>been bent out of shape.

If not broken completely in two.

>It would very much be a drawback if this goes on
>to break legacy code.

I agree.

> Not that I'm suggesting Alexandrescu's idioms appear
>in legacy code... yet.

They will eventually.

>I'm sure the ISO committee consider back-compatibility
>issues.

Obviously, or we wouldn't have some of the leftovers from C (e.g.,
silent conversion from a character literal to char*, if I recall
correctly).

Kaz Kylheku

unread,
Dec 7, 2001, 12:40:06 PM12/7/01
to
In article <38315c2d.01120...@posting.google.com>, Jon Bills wrote:
>The point is that some of Alexandrescu's idioms rely on sizeof() being
>determinable at compile time. dynamic_cast<>() would not fulfil the
>requirements of those idioms. I think you'll find that the idioms rely
>on Standard behaviour of C++, and there is nothing wrong with
>Alexandrescu's
>understanding of the Standard. I believe Steve's posted the code
>somewhere
>else in this thread, so I won't repeat it here.
>
>This leads to the issue that there is / will be a significant number
>of apps built around these idioms and changing sizeof() to be
>evaluated /at runtime only/ will cause those apps to break.

Except that nobody is proposing such a ridiculous thing. In C99, sizeof
expressions continue to be constant, except over VLA's. If VLA's were
introduced to C++, it would be done similarly. So nobody's template
hacks are going to be break over existing operands.

>Personally, I don't see a requirement for
>sizeof() to not be evaluated at compile-time. If VLAs are added to
>C++, surely
>it's possible to overload sizeof() to evaluate only those at runtime?

It's not only possible, but C99 requires it. I wouldn't call
it overloading.

>Adin
>Hunter Baber and Ben Pfaff both posted details of how sizeof()'s
>result can
>continue to be a compile-time constant for existing operands.

This is not different from any other operator, like +

2 + 2 --> constant expression
2 + f() --> non-constant expression

Jon Bills

unread,
Dec 7, 2001, 1:39:25 PM12/7/01
to
"Kaz Kylheku" <k...@ashi.footprints.net> wrote in message
news:W97Q7.31731$nm3.1...@news1.rdc1.bc.home.com...

> In article <38315c2d.01120...@posting.google.com>, Jon Bills wrote:
> >The point is that some of Alexandrescu's idioms rely on sizeof() being
> >determinable at compile time. dynamic_cast<>() would not fulfil the
> >requirements of those idioms. I think you'll find that the idioms rely
> >on Standard behaviour of C++, and there is nothing wrong with Alexandrescu's
> >understanding of the Standard. I believe Steve's posted the code somewhere
> >else in this thread, so I won't repeat it here.
> >
> >This leads to the issue that there is / will be a significant number
> >of apps built around these idioms and changing sizeof() to be
> >evaluated /at runtime only/ will cause those apps to break.
>
> Except that nobody is proposing such a ridiculous thing.

Reading back through the thread, I can see you're correct. I thought
Micah had implied there was a possibility sizeof() would not be a compile-time
constant in future. I've just realised he was talking about the special case
of VLA's and not in general. My mistake.

> In C99, sizeof
> expressions continue to be constant, except over VLA's. If VLA's were
> introduced to C++, it would be done similarly. So nobody's template
> hacks are going to be break over existing operands.

That's what I wanted to hear. I also note your use of the word "hacks". I've
found Alexandrescu's stuff to be incredibly inventive, but it does seem to be
hacking stuff into the language that isn't well supported. Same with Design
Patterns, I guess. I find it slightly amusing that people hold DPs in such high
regard without realising they are hacks around C++, Java and Smalltalk
shortcomings. Only /slightly/ amusing, though. Unfortunately, I have to use
these hacks in my job - suggesting a more appropriate language would likely
raise a few eyebrows. Sad really.

[snip]

Micah Cowan

unread,
Dec 7, 2001, 3:12:56 PM12/7/01
to
Steve Heller <st...@steveheller.com> writes:

> >sizeof certainly cannot be used to determine "whether an object is of
> >some specific type". The best it can do is tell if it's *probably* of
> >some specific type. Nor can sizeof be used to determine
> >convertability. That's what dynamic_cast<>() is for, for crying out
> >loud! If you can refute me with a quote from your "Modern C++
> >Design", that is additionally backed up by the Standard (only
> >authority here), I'd be very interested. I have a feeling its the
> >sort of book I'd be avoiding like the plague, if within its covers
> >such nonsense as this may be found.
>
> Please argue with the author, not me.

What I am trying to get you to do is to post a quote from the book
refuting me. I have no interest in going out to buy a copy just for
the purposes of this thread.

Micah

Micah Cowan

unread,
Dec 7, 2001, 3:17:25 PM12/7/01
to
Steve Heller <st...@steveheller.com> writes:

> "Adam Petersen" <adam.p...@sea.ericsson.se> wrote:
>
> >
> >"Kaz Kylheku" <k...@ashi.footprints.net> wrote in message
> >news:hDZP7.30489$nm3.1...@news1.rdc1.bc.home.com...
> >> In article <hapt0u8klp6qseutj...@4ax.com>, Steve Heller wrote:
> >> >k...@ashi.footprints.net (Kaz Kylheku) wrote:
> >> >
> >> >>In article <j9gs0uoq1ijevg6a4...@4ax.com>, Steve Heller wrote:
> >> >>>k...@ashi.footprints.net (Kaz Kylheku) wrote:
> >> >>>
> >> >>>>In article <ukdo0uck3ljt3gnk4...@4ax.com>, Steve Heller wrote:
> >
> ><snip>
> >
> >> >>sizeof determines size, not type.
> >> >
> >> > sizeof can be used to tell whether one type can be converted into
> >> >another, and whether an object is of some specific type. See "Modern
> >> >C++ Design" for details.
> >>
> >> Are you sure you are not confusing sizeof and typeid?
> >
> >The problem is that Steve is confusing sizeof as part of an idiom and
> >sizeof alone. Alexandrescu shows an excellent technique for detecting
> >*convertibility* at *compile time*. The core of his idea is something like:
>
> I am confusing nothing. What I originally said was that sizeof was
> needed in this idiom. And it is.

Read your quote above: "sizeof can be used to tell whether one type
can be converted into another". You don't mention an idiom, nor that
there are other players.

> >typedef char Small;
> >class Big { char dummy[2]; }
> >Small Test(U);
> >Big Test(...);
> >const bool conv = sizeof(Test(T())) == sizeof(Small);
> >
> >There are more participants here than just a naked sizeof...

And I still don't see how the sizeof, or any of this code, is doing
anything useful. Perhaps there is still information missing.

Micah

Micah Cowan

unread,
Dec 7, 2001, 3:23:15 PM12/7/01
to
jon_...@hotmail.com (Jon Bills) writes:

> This leads to the issue that there is / will be a significant number
> of apps built around these idioms and changing sizeof() to be
> evaluated /at runtime only/ will cause those apps to break.
> Personally, I don't see a requirement for
> sizeof() to not be evaluated at compile-time. If VLAs are added to
> C++, surely
> it's possible to overload sizeof() to evaluate only those at
> runtime?

That's what C already does, as has already been pointed out.

Micah

Steve Heller

unread,
Dec 7, 2001, 4:25:33 PM12/7/01
to
Micah Cowan <mi...@cowanbox.com> wrote:

I've posted it already.

Steve Heller

unread,
Dec 7, 2001, 4:26:50 PM12/7/01
to
Micah Cowan <mi...@cowanbox.com> wrote:

>Steve Heller <st...@steveheller.com> writes:
>
>> "Adam Petersen" <adam.p...@sea.ericsson.se> wrote:
>>
>> >
>> >"Kaz Kylheku" <k...@ashi.footprints.net> wrote in message
>> >news:hDZP7.30489$nm3.1...@news1.rdc1.bc.home.com...
>> >> In article <hapt0u8klp6qseutj...@4ax.com>, Steve Heller wrote:
>> >> >k...@ashi.footprints.net (Kaz Kylheku) wrote:
>> >> >
>> >> >>In article <j9gs0uoq1ijevg6a4...@4ax.com>, Steve Heller wrote:
>> >> >>>k...@ashi.footprints.net (Kaz Kylheku) wrote:
>> >> >>>
>> >> >>>>In article <ukdo0uck3ljt3gnk4...@4ax.com>, Steve Heller wrote:
>> >
>> ><snip>
>> >
>> >> >>sizeof determines size, not type.
>> >> >
>> >> > sizeof can be used to tell whether one type can be converted into
>> >> >another, and whether an object is of some specific type. See "Modern
>> >> >C++ Design" for details.
>> >>
>> >> Are you sure you are not confusing sizeof and typeid?
>> >
>> >The problem is that Steve is confusing sizeof as part of an idiom and
>> >sizeof alone. Alexandrescu shows an excellent technique for detecting
>> >*convertibility* at *compile time*. The core of his idea is something like:
>>
>> I am confusing nothing. What I originally said was that sizeof was
>> needed in this idiom. And it is.
>
>Read your quote above: "sizeof can be used to tell whether one type
>can be converted into another". You don't mention an idiom, nor that
>there are other players.

Read my original quote.

>> >typedef char Small;
>> >class Big { char dummy[2]; }
>> >Small Test(U);
>> >Big Test(...);
>> >const bool conv = sizeof(Test(T())) == sizeof(Small);
>> >
>> >There are more participants here than just a naked sizeof...
>
>And I still don't see how the sizeof, or any of this code, is doing
>anything useful. Perhaps there is still information missing.

I posted the entire header file that contains all the definitions,
and a sample that uses it.

Jon Bills

unread,
Dec 8, 2001, 9:41:54 AM12/8/01
to
Micah Cowan <mi...@cowanbox.com> wrote in message news:<yu8her2...@mcowan-linux.transmeta.com>...

Yeah, I managed to mung my understanding of the discussion halfway
through the thread. My understanding has now been unmunged.

0 new messages