[comp.lang.c] The Dangers of sizeof

penneyj@servio.UUCP (D. Jason Penney) (04/08/89)

In article <510@lakesys.UUCP> chard@lakesys.UUCP (Chad Gibbons) writes:
> sizeof comes in two flavors, sizeof(type) and sizeof object.  In the
> latter case the object-expression is not evaluated, only its type is
> used.  Therefore the above usage is perfectly legitimate.  As to
> whether it is better or worse than the alternative style, there
> don't seem to be really strong arguments on either side.  I personally
> prefer sizeof(type) since to me the other form is just a corruption of
> this fundamental definition, but I'm sure other programmers disagree.
> It doesn't seem to be worth arguing about..


I must disagree!  There is only ONE form of sizeof -- the operator form,
which takes an arbitrary (unevaluated) expression as its argument.

sizeof (aType) is actually the same as

sizeof (aType)(1)

(i.e, casting the empty expression).  People who uniformly treat sizeof
as if it were a function run a grave risk.  Trick question:  what is the
value of:

sizeof (char) - 1

Answer:  1 -- the (char) is a cast, which is of higher precedence than
sizeof, hence it parses as,

sizeof ((char)(- 1))

I recommend ALWAYS using the operator form of sizeof and parenthesizing
the entire sizeof expression for safety.  Note:  you MUST parenthesize
the operand of sizeof if it is a type:

(sizeof (char)) - 1

-- 
D. Jason Penney                  Ph: (503) 629-8383
Servio Logic Corporation       uucp: ...ogccse!servio!penneyj
15220 NW Greenbrier Parkway #100
Beaverton, OR 97006

acu@mentor.cc.purdue.edu (Floyd McWilliams) (04/10/89)

In article <105@servio.UUCP> penneyj@servio.UUCP (D. Jason Penney) writes:

>sizeof (aType) is actually the same as

>sizeof (aType)(1)

>(i.e, casting the empty expression).  People who uniformly treat sizeof
>as if it were a function run a grave risk.  Trick question:  what is the
>value of:

>sizeof (char) - 1

>Answer:  1 -- the (char) is a cast, which is of higher precedence than
>sizeof, hence it parses as,

>sizeof ((char)(- 1))

	Oh really?  Then take a look at this:

--
Script started on Sun Apr  9 13:41:38 1989
tcsh% more foo.c
#include        <stdio.h>

main()

{
  printf("sizeof(char) - 1 == %d.\n",sizeof(char) - 1);
}
tcsh% cc foo.c
tcsh% a.out
sizeof(char) - 1 == 0.
tcsh% 

script done on Sun Apr  9 13:42:09 1989
--

>I recommend ALWAYS using the operator form of sizeof and parenthesizing
>the entire sizeof expression for safety.  Note:  you MUST parenthesize
>the operand of sizeof if it is a type:

>(sizeof (char)) - 1

	"sizeof" may not be a function, but it does have a high precedence
(it's a unary operator).  If what you posted were true, then everyone who
tried a "sizeof(foo) + CONST" under pre-ANSI standard C would have been
screwed; C didn't have a unary plus.

--
"Life's for my own, to live my own way."
Floyd McWilliams			mentor.cc.purdue.edu!acu

maart@cs.vu.nl (Maarten Litmaath) (04/11/89)

penneyj@servio.UUCP (D. Jason Penney) writes:
\...
\I must disagree!  There is only ONE form of sizeof -- the operator form,
\which takes an arbitrary (unevaluated) expression as its argument.

K&R seem to disagree.

\...  Trick question:  what is the value of:
\
\sizeof (char) - 1
\
\Answer:  1 -- the (char) is a cast, which is of higher precedence than
\sizeof, [...]

sizeof and casts have equal precedence.

	% cat c.c
	main()
	{
		printf("%d\n", sizeof(char) - 1);
	}
	% a.out
	0
	%

People, please CHECK things before posting.
-- 
 "If it isn't aesthetically pleasing, |Maarten Litmaath @ VU Amsterdam:
  it's probably wrong." (jim@bilpin). |maart@cs.vu.nl, mcvax!botter!maart

guy@auspex.auspex.com (Guy Harris) (04/11/89)

 >I must disagree!

So must I, but that's because I know for a fact that you're wrong.

 >There is only ONE form of sizeof -- the operator form,
 >which takes an arbitrary (unevaluated) expression as its argument.

Wrong.  "sizeof" is, indeed, an operator in both forms; however, the
notion that

 >sizeof (aType) is actually the same as
 >
 >sizeof (aType)(1)
 >
 >(i.e, casting the empty expression).

is not backed up by any language specification I've seen.  K&R I has two
separate grammar rules for the two forms; the December 7, 1988 (d)pANS
says that

	...The 'sizeof' operator yields the size (n bytes) of its
	operand, which may be an expression or the parenthesized name of
	a type.

 >Trick question:  what is the value of:
 >
 >sizeof (char) - 1
 >
 >Answer:  1 -- the (char) is a cast, which is of higher precedence than
 >sizeof, hence it parses as,
 >
 >sizeof ((char)(- 1))

Yeah, that must *be* a trick question, considering you got it wrong. 
The answer is 0, not 1; the "(char)" is *NOT* a cast, it's part of the
"sizeof" expression, so it parses as

	(sizeof (char)) - 1

Are you sure you didn't mean to post this on April 1?

richard@pantor.UUCP (Richard Sargent) (04/13/89)

acu@mentor.cc.purdue.edu (Floyd McWilliams) wrote in article 
<2280@mentor.cc.purdue.edu>:

> In article <105@servio.UUCP> penneyj@servio.UUCP (D. Jason Penney) writes:
> 
> [Discussion of how "sizeof (char) - 1" is 1 not 0.]
> 
> 	Oh really?  Then take a look at this:
> 
> --
> [Script to prove it ain't so.]
> --
> 
> 	"sizeof" may not be a function, but it does have a high precedence
> (it's a unary operator).  If what you posted were true, then everyone who
> tried a "sizeof(foo) + CONST" under pre-ANSI standard C would have been
> screwed; C didn't have a unary plus.
> 

Quite right!  I quote K&R, Section 7.2 Unary Operators, pages 187-188
(first edition).  The very last paragraph of the section, on page 188,
reads:

   "The construction  sizeof( type )  is taken to be a unit, so the
    expression  sizeof( type ) - 2  is the same as  (sizeof( type )) - 2."

QED.
Richard Sargent
Systems Analyst

walter@hpclwjm.HP.COM (Walter Murray) (04/14/89)

> Trick question:  what is the value of:
> 
> sizeof (char) - 1
> 
> Answer:  1

I know that many others will point out that this is wrong.  But wait:
there *IS* reason for confusion. 

If you just look at page 49 of K&R (page 53 in the 2nd edition), 
you will think that sizeof, (type), and unary - are operators with
the same precedence, and that they associate right-to-left.  By that,
the answer *SHOULD* be 1, shouldn't it?  

On page 188 (first edition) you find "the rest of the story":  They tell
you that sizeof(type) "is to be taken as a unit".  In other words,
the sizeof operator actually has higher precedence than a cast.  In the
second edition, I can't find any place where that is spelled out in so
many words, though it does follow from the syntax rules that are given.
(A "cast-expression" is now distinct from a "unary-expression".)  

I hope the precedence table gets updated in some future edition.  Another
problem in the table (troublesome only for novices) is that operators
like "-" appear twice, once as unary and once as binary.  But now I'm
drifting.

Back to the original problem, Harbison & Steele also comment on it
(2nd edition, page 156).  They see it as a syntactic ambiguity which
is resolved arbitrarily.

The pANS resolves it, of course, by having unary operators (like
sizeof) at a higher precedence than cast operators.

Walter Murray
-------------

penneyj@servio.UUCP (D. Jason Penney) (04/15/89)

I've got egg all over my face on this one.  I won't even offer much
of an excuse for this -- my misimpression arose from some kind of glitch
using a VAXC compiler (VMS 4.X) which definitely misparsed an expression
similar to

sizeof (char) - 1

but is definitely unambigous and should have the value 0.

My profound apologies.