sizeof with arith expr

P

PGK

Hi all,

Assuming sizeof on expressions is valid, how does a cpp compiler
evaluate something like:

char c;
std::cout << sizeof (c+c);

For this, GCC 4.3.2 gives me a result of 4. Is this result always ==
sizeof(int)?

Is this correct: sizeof (e) is the largest sizeof from all the
individual terms of e, rounded up to sizeof (int)?

Cheers,
-Graham
 
P

peter koch

Hi all,

Assuming sizeof on expressions is valid, how does a cpp compiler
evaluate something like:

char c;
std::cout << sizeof (c+c);

For this, GCC 4.3.2 gives me a result of 4. Is this result always ==
sizeof(int)?

Is this correct: sizeof (e) is the largest sizeof from all the
individual terms of e, rounded up to sizeof (int)?

No. sizeof returns the size of the type of the expression (without
evaluating it). Due to integral promotion, "c + c" is of type "int",
and thus sizeof(c + c) is the same as sizeof(int).

/Peter
 
P

PGK

No. sizeof returns the size of the type of the expression (without
evaluating it). Due to integral promotion, "c + c" is of type "int",
and thus sizeof(c + c) is the same as sizeof(int).

/Peter

Isn't that what I said? Can you say more on "integral promotion"?
 
J

James Kanze

Isn't that what I said?

No. You said that sizeof is the largest sizeof from all
individual terms of e, rounded up. That's completely false:
sizeof is the size of the type of the expression. In this case,
int, because in this case, integral promotion gives each of the
operands a type int, but integral promotion doesn't apply for
everything, and there are even operations which can reduce the
size. Each operator or sub-expression has a defined type,
depending on the type of its operands.
Can you say more on "integral promotion"?

It's a rule that says that in certain contexts, integral types
smaller than int are systematically converted to int. It
applies whenever the "usual arithmetic conversions" apply, i.e.
for most (but not all) binary operators. Integral promotion
also occurs in a few other contexts, such as when passing an
argument to a vararg.
 
P

PGK

No.  You said that sizeof is the largest sizeof from all
individual terms of e, rounded up.  That's completely false:
sizeof is the size of the type of the expression.  In this case,
int, because in this case, integral promotion gives each of the
operands a type int, but integral promotion doesn't apply for
everything, and there are even operations which can reduce the
size.  Each operator or sub-expression has a defined type,
depending on the type of its operands.


It's a rule that says that in certain contexts, integral types
smaller than int are systematically converted to int.  It
applies whenever the "usual arithmetic conversions" apply, i.e.
for most (but not all) binary operators.  Integral promotion
also occurs in a few other contexts, such as when passing an
argument to a vararg.

--
James Kanze (GABI Software)             email:[email protected]
Conseils en informatique orientée objet/
                   Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Thanks for the insight James. Here's my algorithm applied to an
example:

char c;
short s;
int i;
sizeof(c + s / i) = max2 (sizeof int) (max3 (sizeof c) (sizeof s)
(sizeof i))

Which gives the correct answer. Is there an example where this
wouldn't work?
(I'm basically outlining the steps to evaluate the type, as performed
by the compiler.)

-G
 
A

Alf P. Steinbach

* PGK:
char c;
short s;
int i;
sizeof(c + s / i) = max2 (sizeof int) (max3 (sizeof c) (sizeof s)
(sizeof i))

The part after the '=" like Lisp, anyway it isn't C++ unless you have defined a
function max2 that produces a functor, and ditto for max3, which is unlikely.

Which gives the correct answer. Is there an example where this
wouldn't work?

The above is, technically, under the assumptions stated, one such example. ;-)

But rewritten to valid C++ I don't think there's any example where the size of
an expression that involves only built-in operators, won't be the sizeof the
largest operand after integral promotion.

Basically, in an expression involving only built-in operators and no casts, the
"usual arithmetic conversions" are applied, and they're designed to generally
not lose information, i.e. never converting down to smaller size.

But, they're flawed, because the type of an expression can depend on the ranges
for various built-in types, which means that it can depend on the compiler.

It's pretty much inconceivable that there could be any case whatsoever where
that would be of practical utility, rather than just generating more work...

(I'm basically outlining the steps to evaluate the type, as performed
by the compiler.)

Then you need to emulate the usual arithmetic conversions; as I recall they're
at start of section 5 of the standard (well, unless it was 3, whatever, check).

Note, as I remarked above, that in some cases the result is compiler-dependent.


Cheers & hth.,

- Alf
 
J

James Kanze

Thanks for the insight James. Here's my algorithm applied to
an example:
char c;
short s;
int i;
sizeof(c + s / i) = max2 (sizeof int) (max3 (sizeof c) (sizeof s)
(sizeof i))
Which gives the correct answer. Is there an example where this
wouldn't work?

char a[2] ;
sizeof( a[ 0 ] ) ;

char f( int ) ;
sizeof( f( 42 ) ) ;

And if int is larger than float:
float f ;
sizeof( f + 1.0F ) ;
(I don't know of any such implementations, but they certainly
could exist.)

If you limit your expressions to the usual arithmetic operators,
without any array accesses, pointer dereferences, and such, your
algorithm will probably work. But why create an algorithm for
just a limited set of cases, which neglects information you need
to know anyway?
 
J

James Kanze

But rewritten to valid C++ I don't think there's any example
where the size of an expression that involves only built-in
operators, won't be the sizeof the largest operand after
integral promotion.

sizeof( static_cast< char >( 1000000 ) ) ;

:). Anything involving pointer dereferencing (including array
access) or function calls, too.
Basically, in an expression involving only built-in operators
and no casts, the "usual arithmetic conversions" are applied,
and they're designed to generally not lose information, i.e.
never converting down to smaller size.

The "usual arithmetic conversions" are only applied when the
standard says that they're applied. As I said earlier, you can
end up with smaller types: dereferencing a pointer can result in
a char, even if the expression of the pointer type contains
ints, e.g. *(p + 42), or p[42], which is the same thing.
 
A

Alf P. Steinbach

* James Kanze:
sizeof( static_cast< char >( 1000000 ) ) ;

:). Anything involving pointer dereferencing (including array
access) or function calls, too.

Note that this thread is about: "sizeof with arith expr".

Other examples where you explicitly choose some type include indexing and member
access.

So much should be obvious, but I fail to see, stupid that I am, but I think I'm
getting an inkling now: all these pedantic "fill in the details" postings, with
wording as if each extra detail was some kind of correction of the quoted
material, it's not that you really think these postings are needed, is it?

The "usual arithmetic conversions" are only applied when the
standard says that they're applied.

Of course the arithmetic conversions are only applied when they are applied.

Was this detail necessary?

What about the implication that it somehow corrected something?

As I said earlier, you can
end up with smaller types: dereferencing a pointer can result in
a char, even if the expression of the pointer type contains
ints, e.g. *(p + 42), or p[42], which is the same thing.

You can't do that with only arithmetic operators. This thread is about
arithmetic expressions. The OP's example is about that, and the title.


Cheers & hth.,

- Alf
 

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

Members online

No members online now.

Forum statistics

Threads
473,774
Messages
2,569,599
Members
45,169
Latest member
ArturoOlne
Top