sizeof() calculated at compile time or run time


C

CodeMonk3y

gotta question on sizeof keyword

does the sizeof keyword calcuates the size at compile time or run time ??



-- Posted on news://freenews.netfront.net - Complaints to (e-mail address removed) --
 
Ad

Advertisements

D

Default User

For the OP, sizeof is an operator.
At compile time.

I haven't been keeping up with the changes coming to the standard. Are
variable-length arrays (currently in C99) being added? That's one case
where sizeof is a run-time construct, as the size of such an array
can't be determined at compilation. It's not something really needed in
C++, with std::vector and all.




Brian
 
D

Default User

Alf said:
* Default User:

No.

I thought it unlikely.
It might be so in C99, but presumably if variable length array
support was added in C++ it would not be so in C++.

Er, what? How would you have C99-style VLAs that could be sized at
compilation?
Current practice says otherwise. Several compilers support e.g.
_alloca, to do in an unsafe way what variable length array support
could do simply and safely.

Do they support that specifically for C++, or is it a holdover from C
extensions?



Brian
 
D

Default User

Alf said:
* Default User:

Why should C++ variable length array be C99-style?

Unless you bend the definition to where it's meaningless, then I don't
see how any array that can be dynamically created can yield its size at
compile time.
But anyway, given that, it would still be problematic in C++ to let
sizeof yield the dynamic size of such an array.

C++ has other means. In C++ you don't expect sizeof to e.g. yield the
dynamic size of a string. Similarly for dynamic arrays.

Not similarly at all. "Array" means something in both C and C++. You
expect sizeof an array to give you the size of the array. std::string
is a totally new thing, part of the selection of container classes.
Those include methods for determining the size.

Either the syntax and semantics of this "VLA" would have to be so
different as to call into question calling it an array, or you're going
to need some sort of dynamic sizeof operator. I'm not sure why you're
so resistant to the very idea.

I suspect that if VLAs ever do make it into C++, they will look a lot
like C99. Your opinion may vary.


[alloca]
Neither. It's for both languages. See e.g.
http://docs.sun.com/app/docs/doc/819-2243/alloca-3c.

That tells you what it is, not why it's available in C++. It suspect
that it was created for C, and used in C++ pre-STL/std. I think it's
more a holdover than something they feel is specifically needed for C++
(if they even think about it much).




Brian
 
D

Default User

Alf said:
* Default User:

In other words, you now see that your earlier notion was ludicruous.

No, I don't.
Could it be that you misunderstood something?

I'm not following.
I do not expect what you write in the context of a more abstract
array.

I'm not even sure what this is trying to say.
And I think you do not expect sizeof(v) where v is std::vector to
yield dynamic size.

No, I don't. Why would I? A vector is not an array. It has a member
function for yielding the size. A array does not.
Yet std::vector is an array,

No, it is not. It is a standard container. Arrays are defined in the
standard already. Vectors are not arrays.

I now see that you are the one confused.




Brian
 
Ad

Advertisements

D

Default User

Alf P. Steinbach wrote:

You wrote "You expect sizeof an array to give you the size of the
array". That is false in general. It is only true for a very specific
narrow meaning of "array" (see below), which means that here you're
into terminology discussion.

Which is the definition of array used in C++.

There's a reason they didn't call it std::array.
Consider what distinguishes "raw array" from "array".

Nothing, as there is no such thing yet.

At any rate, you have nothing to back up your statements. Knowing your
history, you aren't willing reasonably discuss these things, so I'll be
killing this thread. You can post your arguments to whomever else might
be interested.



Brian
 
I

Ian Collins

Alf said:
Hm, ending on a personal attack with insinuations & the works, plus
snipping what contradicts your earlier arguments.
I thought dummy spitting is what Usenet is all about :)
 
J

James Kanze

* Default User:
Why should C++ variable length array be C99-style?
But anyway, given that, it would still be problematic in C++
to let sizeof yield the dynamic size of such an array.

*IF* C++ were to add VLA, there are only two possible choices
with regards to sizeof: make it illegal on a VLA, or say that it
is not a constant if used on a VLA. Since the major argument in
favor of VLA in C++ is C compatibility, I suspect that the
latter would be chosen. But it's really just another question
which would have to be addressed. There are a certain number of
complexities with the way VLA's interact with classes as well,
and apparently, no one felt that they were important enough to
do the work necessary to integrate them into C++.
C++ has other means. In C++ you don't expect sizeof to e.g.
yield the dynamic size of a string. Similarly for dynamic
arrays.
Neither. It's for both languages. See
e.g.http://docs.sun.com/app/docs/doc/819-2243/alloca-3c.

Which doesn't mean that it isn't a hold-over from the stone
age:). We have a lot of things which are the same for both
languages in that category.
 
J

James Kanze

Alf P. Steinbach wrote:

[...]
I suspect that if VLAs ever do make it into C++, they will look a lot
like C99. Your opinion may vary.

Probably, since the only motivation ever expressed (at least
before the committee) for adding them to C++ was C
compatibility. Since class/struct have somewhat different
semantics in C++ than in C, it would take some adapting to make
them fit into the C++ model. And since no one felt that they
added enough value to be worth the work, C++ didn't adopt them.
That tells you what it is, not why it's available in C++. It
suspect that it was created for C, and used in C++
pre-STL/std. I think it's more a holdover than something they
feel is specifically needed for C++ (if they even think about
it much).

It's very much a hold-over, a hack from Berkley Unix, still
maintained in order to avoid breaking (very) old code. It's not
normally used in modern C, either. (On the other hand, I can
very well imagine that some code C++ written back in the 1980's
used it.)
 
M

Marcel Müller

James Kanze wrote:
[alloca]
It's very much a hold-over, a hack from Berkley Unix, still
maintained in order to avoid breaking (very) old code. It's not
normally used in modern C, either. (On the other hand, I can
very well imagine that some code C++ written back in the 1980's
used it.)

From time to time alloca is useful. I use alloca infrequently as
alternative to local scoped pointers since it is a performant way with
similar semantics like exception safety of the storage (but not the
stored object, of course). Unfortunately the behavior is not integrated
into the C++ language. This makes it difficult (or impossible?) to write
a safe wrapper around it, because the storage duration is not sufficient
when alloca is called from an inline function. In fact, most compilers
take the storage from the next enclosing function that is not expanded
inline. But this is implementation dependent and not portable in any
way. Therefore the call to the placement new operator

From my point of view it would be helpful in some applications to have
something like a 'stack allocator', which uses alloca for allocation and
a no-op for deallocation. But this can't be done for the above reasons.

The only work around, that I know, is to use a (logically constant)
scoped pointer with a custom deleter, that only calls the destructor
explicitly. The pointer must be initialized with the placement new
operator and alloca/sizeof. Of course, this looks bad and is error-prone.


Marcel
 
Ad

Advertisements

T

Thomas J. Gritzan

Alf said:
* James Kanze:

No, that's incorrect.

Instead of those silly, problematic choices, there is always the
rational choice, of letting sizeof do what it already does in all other
cases, providing the known compile time size (as for e.g. string and
vector).

It beats me how you could forget that.

He forget that because a C99 VLA doesn't have a "known compile time size".
Since that argument has been defeated (as well it should be, IMHO! :)
), if VLAs were adopted it would presumably be due to some better
argument such as practical need demonstrated by existing practice using
unsafe alternatives.

But there already is a safe alternative, so there is little need for
another semi-safe alternative.
 
J

James Kanze

* James Kanze:
No, that's incorrect.

Formally, yes. The standard could always define it to return 42
if used on a VLA:) Practically, however... (Actually, you may
be right. There are some good arguments for having sizeof of a
VLA always evaluate to zero. It's a possibility I hadn't
considered.)
Instead of those silly, problematic choices, there is always
the rational choice, of letting sizeof do what it already does
in all other cases, providing the known compile time size (as
for e.g. string and vector).

Which is? VLA's don't have a known compile time size. If not,
they wouldn't be VLA's.
It beats me how you could forget that.

Maybe because I'm familiar with what a VLA is.
Since that argument has been defeated (as well it should be,
IMHO! :) ), if VLAs were adopted it would presumably be due
to some better argument such as practical need demonstrated by
existing practice using unsafe alternatives.

To date, no one has put forward a better argument, at least not
to the committee.
Here you're talking about additional reasons why C99 VLAs are
a braindead notion for C++, yes?
In short, for C++ C99 VLAs are an ungood implementation of VLAs.

No. It's actually a very good implementation. But it would
require some work to adapt, like just about everything else.
Unlike many other things (e.g. the new integral types),
apparently no one felt it was worthwhile.
Uhm, the addition operation is a hold-over from the stone age.
That does not detract from the usefulness and desirability of addition.

There is a difference. The addition operator is actually used
in serious programs. Every coding guideline I've seen for C has
banned alloca.
It would be nice with a safe modern notation such as '+', for
that operation.

It would be nice if it were rigorously defined in all cases,
with no undefined behavior.
 
J

James Kanze

* Thomas J. Gritzan:

[...]
There is no safe alternative today.

You mean you've never heard of std::vector?
Your use of the term "semi-safe" is argumentative and a slur
on the C++ standardization committee, presuming as a matter of
course that they would choose something only semi-safe.

Just the opposite. Both Thomas and the committee agree that
there is no need for the semi-safe alternative of alloca. (Note
that alloca is so unsafe that even the C committee couldn't be
brought to buy it.)
Do you really find the committee's decisions so generally
incompetent that that can be presumed?

You're the one disagreeing with their decision (by default, to
not adopt VLA's or alloca), not Thomas.
 
V

Vidar Hasfjord

VLA's don't have a known compile time size.  

This and the other characteristics of VLAs makes them even more
peculiar than static arrays; which already is the most striking type
irregularity in C++. A VLA is not a first-class object. It can only
live on the stack; i.e. function scope. It cannot be copied or
aggregated. As far as type is concerned it only decays to a pointer.

My conclusion is that the VLA feature is more of an allocation
mechanism than a type. Rather than adopt VLAs, i.e. another irregular
array type, I think C++ should rather focus on a dynamic stack
allocation mechanism and find a way to make that accessible to any
type.

Here's an superficial idea I shared on stack allocation in a previous
thread ("size of array is not an integral constant-expression"):

In my view a better solution for dynamic stack allocation in C++
would
be a lower-level feature; as support for a standard library class.
The
ideal would be a general "allocation overload" mechanism for
constructors, so that you can differentiate between construction on
the stack and on the heap. Then some mechanism for allocating stack
space would be used by the "stack constructor". This would allow any
library type, e.g. std::vector, to be optimized for stack allocation.

An idea would be for the language to automatically pass an extra
parameter to the constructor if an object is constructed on the
stack.
This parameter has a built-in type, say std::auto_allocator, which
allows allocation of stack space in the parent frame; i.e. the stack
frame in which the construction takes place. For example,

vector (size_t n, std::auto_allocator& a)
: buf (a.alloc (n * sizeof T)) {...}

Aside: Many C++ implementations provide a stack allocation feature as
an extension (alloca). Unfortunately, alloca cannot be used to create
a data type that mimics a VLA since it allocates memory in the stack
frame of the caller; i.e. you will have to call it explicitly; it
cannot be encapsulated.

Regards,
Vidar Hasfjord
 
J

James Kanze

* James Kanze:
* Thomas J. Gritzan:
Alf P. Steinbach schrieb:
[...]
Since the major argument in
favor of VLA in C++ is C compatibility, I suspect that the
latter would be chosen.
Since that argument has been defeated (as well it should
be, IMHO! :)), if VLAs were adopted it would presumably
be due to some better argument such as practical need
demonstrated by existing practice using unsafe
alternatives.
But there already is a safe alternative, so there is
little need for another semi-safe alternative.
There is no safe alternative today.
You mean you've never heard of std::vector?
std::vector is not an alternative when you want fast stack
allocation.

What does it matter where the memory is allocated? And as for
speed, that's really a question of optimization---good
allocators can be very, very fast too.
You know that.

I don't see what VLAs buy me that std::vector doesn't.
That's meaningless and you know it.

It's a direct rebuttal of your statement that Thomas made a slur
on the C++ standardization committee. Thomas and the committee
are apparently in complete agreement: there is no need for a
semi-safe, alloca based solution.
There is no single "the" alternative.
And that non-existent thing is not semi-safe.

What non-existent thing? VLA's and alloca exist in C, so we can
judge them.
You're doing the same as Thomas.

You mean being reasonable, and understanding the issues.
You're saying the committee would not be able to come with
something competently designed, only "semi-safe" -- but that
reflects on yourself, as a member.

No. We're saying that the committee has already provided a
relatively safe alternative (std::vector), so there's no need to
to adopt a semi-safe solution (VLA's or alloca).
That is untrue and you know it; I haven't argued for adoption
of either alloca or C99 VLAs.

So what are you arguing. If we all agree that std::vector is
sufficient, and nothing else is needed, there's no need to
argue.
 
Ad

Advertisements

J

James Kanze

* James Kanze:
ITYM that *the C99 standard* defines no compile time size for
C99 VLAs.

By definition, a VLA doesn't have a size known at compile time.
That's what the V means: variable.
In practice the fixed size is the size of a pointer or offset.

Where does the pointer suddenly come from? A VLA does convert
implicitly into a pointer, just like any other C style array,
but it's not a pointer, and it doesn't imply a pointer in any
way.
For a C++ VLA it would be that or a higher fixed size (the
pointer or offset is practically unavoidable), e.g. see some
way below.
ITYM that if C99 VLAs didn't conform to C99 standard they
wouldn't be C99 VLAs.

The V in VLA means variable. If the size isn't variable, then
its not a VLA. At least in English.
Yes, it's easy to get trapped in familiar notions, where
anything else seems impossible or doesn't pop up when one
tries to list possibilities.

Or to be trapped by the actual meaning of words in the English
language? The V in VLA means variable. Not a compile time
constant.
Other examples include inability of people to imagine
reasonable semantics for virtual constructors, even teachers
asking students to provide rationalizations why they "can not"
exist (this teaches the students the entirely wrong thing,
namely to rationalize and conform instead of to think
critically independently).

It's actually a good test to see if the student has understood
what virtual means. I'm not sure myself what you mean by a
virtual constructor.
And not to mention the example of static virtual member
function! :)

The problem there is more that no one has ever found a use for
them. What's the point of declaring a function static if you
need an object on which to call it?
I guess it's one of those features that you don't know you
need until you've been exposed to it.

So you're saying that that no one in the committee has been
exposed to C99? Or to alloca? I have a hard time believing
that.
In Windows, where since early 1990's there's been this divide
between narrow and wide characters, alloca() is much used.

With which compiler? I couldn't find it in the Microsoft
documentation. I did find an _alloca, which looks very much
like the traditional alloca, but the documentation said it is
deprecated.
Not only by the API itself, but also in Microsoft's and
others' libraries, usually via macros. But I guess the need
for converting beween narrow and wide strings hasn't been that
great on *nix.

Typically, no. UTF-8 rules:).

In practice, of course, you do choose one internally, either
UTF-8 or UTF-32, and the conversion occurs at the IO level.

Independently of that, however: what does alloca do here that
std::vector doesn't. I'd say, in fact, that alloca isn't
usable, because you can't realloc, when you find you don't have
enough space. (And you can't really know the length of the
results until you've converted.)
But this is a very interesting question because it brings up
all kinds of nifty usage scenarios, which suggest something
more powerful than C99 VLAs for C++. For example, one
scenario is a function that receives two string arguments,
concatenates them and possibly some more small strings, uses
the concatenation result as a file path and returns handle to
opened file. Here with the strings as simple C strings old
alloca() or a C99 VLA can be used for the result string, very
efficient, but if strings are abstracted in class, efficiency
is difficult!

Now you're kidding. I use std::string for this all the time,
and I've never had the slightest performance problems. At least
on the implementations I use, I can do an awful lot of dynamic
allocation, and the actual time needed is still not even
measurable compared to the time necessary to open a file.
I guess what's needed is some language feature that can pass a
computation of required memory size to alloca() (so that
alloca() can be performed in clean stack frame), and then make
result of alloca() available to the class instance.

Actually, what is needed is just an efficient heap allocator.
Something which all of the systems I normally use have.
And language definition, C++ standard, would have to state
that auto_alloc_ptr or derived class can only be instantiated
by declaring a local variable.

And maybe not in a catch block (Microsoft, at least, says that
its _alloca function should not be used in an exception
handler).
For minimum fixed size of a VLA, i.e. sizeof( myVLAinstance ),
consider
template< typename T >
class vla: private auto_alloc_ptr<T>
{
// ...
};
I think you can see the picture (regarding sizeof) now, yes?

I think that all you're proposing is a somewhat limited version
of auto_ptr, with a (hopefully) faster allocator. I don't see
what that buys us compared to std::vector (with a fast
allocator). And you've yet to show a use case scenario where
std::vector (even with the standard allocator) wouldn't be
superior.

And it has nothing to do with VLA's (which are arrays, not
pointers).

[...]
Why place more strict requirements on VLA than on any other
type?
Any other type has UB if the stack overflows.
It would be silly to require VLA to not be UB in that case.

That's the way C does it. So what you really want is the C
style VLAs. Except that the use case you describe requires
either allocating a worst case maximum (and thus either doing a
lot of additional calculations up front, or guaranteeing stack
overflow), or dyanamic resizing (which isn't possible with VLAs
or alloca).
 
J

James Kanze

This and the other characteristics of VLAs makes them even
more peculiar than static arrays; which already is the most
striking type irregularity in C++. A VLA is not a first-class
object. It can only live on the stack; i.e. function scope.

That's not true in C, although there are some restrictions.
It cannot be copied or aggregated.

It can certainly be aggregated in C, although it must be the
last element in a structure. And it can be copied in the same
way you copy any array in C: with memcpy.
As far as type is concerned it only decays to a pointer.

No. It has an array type.
My conclusion is that the VLA feature is more of an allocation
mechanism than a type.

Not at all, although from another posting, I gather that that is
what Alf really wants: not VLAs, but a type-safe alloca.
(Something which bears the same relation to alloca that the new
operator bears to malloc. Perhaps a special placement new?)
Rather than adopt VLAs, i.e. another irregular array type, I
think C++ should rather focus on a dynamic stack allocation
mechanism and find a way to make that accessible to any type.

Why? What does that buy us?

[...]
Aside: Many C++ implementations provide a stack allocation
feature as an extension (alloca).

Typically, only because it's part of the basic C library,
inherited from Berkley Unix, many, many years ago. In practice,
it's not used in well written code, and none of the
standardization organizations have wanted anything to do with
it. (It's not Posix, nor standard Unix.)
 
G

gpderetta

Actually, what is needed is just an efficient heap allocator.

Amen. And automatic optimization of heap allocation to stack
allocation when escape analysis proves it is safe (and the size is
bounded) . This is something that Java compilers have been doing for a
while, probably there are c++ compilers that do it too, but not those
I'm familiar with.
 
Ad

Advertisements

J

James Kanze

Amen. And automatic optimization of heap allocation to stack
allocation when escape analysis proves it is safe (and the
size is bounded) . This is something that Java compilers have
been doing for a while, probably there are c++ compilers that
do it too, but not those I'm familiar with.

It's far more difficult (if not impossible) in C++ because C++
doesn't allow compacting garbage collection. You can't move
objects around in C++.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top