henry@utzoo.UUCP (Henry Spencer) (05/13/84)
Here's an entertaining oddity in C. Try running the following under
your favorite C compiler:
----
main(){
int x = 1;
printf("%u\n", sizeof(x++));
printf("%d\n", x);
}
----
The result of the first printf is uninteresting, just whatever the
size of an integer is on your machine. The result of the second
printf is the good part. Looks like x should have been incremented
by the autoincrement, so it should be 2. Surprise -- on every system
handy locally, it's 1! (This includes V7, 4.1BSD, 4.2BSD, Amdahl UTS,
and several varieties of 68K.)
The fact is, most C compilers don't generate code for the expression
inside sizeof at all. Once they know what type it is, the result of
the sizeof is fully defined, so "of course" the details of the operand
no longer matter. But nowhere in K&R is there anything that would
permit this wanton disregard of side effects, unless you really work
the statement "...this expression is semantically an integer constant..."
hard.
I agree that the behavior as implemented is reasonable and should be
classed as "correct", but this needs to be more explicitly documented.
Anybody know whether the ANSI C committee has noticed this one?
--
Henry Spencer @ U of Toronto Zoology
{allegra,ihnp4,linus,decvax}!utzoo!henry
dmmartindale@watcgl.UUCP (Dave Martindale) (05/13/84)
Another interesting one is: #define MSG "this is some string or other" ... l = sizeof(MSG); In the compilers I'm familiar with, the string is dumped out into the data space of the program, even though the compiler does evaluate the size at compile time and the string will never be referenced.
dan@idis.UUCP (Dan Strick) (05/14/84)
I would think it unreasonable to apply sizeof to anything that does not name a storage area (i.e. is not an l-value). X++ is not an l-value. Dan Strick [decvax|mcnc]!idis!dan
opus@drutx.UUCP (ShanklandJA) (05/15/84)
Joey Duhon (ihuxj!duhon) writes:
On page 126 we read "The expression sizeof(object) yields an
integer equal to the size of the specified object. ... The object can be
an acutual variable or array or structure, ..."
I don't see anything here about other expressions.
The confusion seems to be over the reference manual which indicates
that the grammar will accept "sizeof expression" syntactically.
This is obviously a shortcut for the compiler writer(s).
However, the semantic interpretation is explained above(p.126).
This all seems clear to me.
Good point, but we've still got a compiler problem here, I'd say.
If sizeof( x++ ) is really a semantic error, then the compiler ought
to be complaining about it, rather than quietly doing its own thing,
whatever that may be. Undeclared variables are also permitted by
the C syntax -- that is, they are a semantic error -- but I imagine
howls would be heard far and wide (mine certainly would be) if a C
compiler issued no error message for an undeclared variable, and issued
code that dumped core the first time that variable was referenced or
assigned to.
Jim Shankland
..!ihnp4!druxy!opus
duhon@ihuxj.UUCP (duhon) (05/15/84)
Having read all the speculation about what "sizeof expression" should present, I thought I'd read the manual ("The C Programming Language," Kernighan and Ritchie). On page 126 we read "The expression sizeof(object) yields an integer equal to the size of the specified object. ... The object can be an acutual variable or array or structure, ..." I don't see anything here about other expressions. The confusion seems to be over the reference manual which indicates that the grammar will accept "sizeof expression" syntactically. This is obviously a shortcut for the compiler writer(s). However, the semantic interpretation is explained above(p.126). As an aside, "Programming in C," by Kockan says the following: "The argument to the sizeof operator can be a variable, an array name, the name of a basic data type, or the name of a derived data type." This all seems clear to me. Joey Duhon ihnp4!ihuxj!duhon
henry@utzoo.UUCP (Henry Spencer) (05/17/84)
Joey Duhon says, in part: Having read all the speculation about what "sizeof expression" should present, I thought I'd read the manual ("The C Programming Language," Kernighan and Ritchie). On page 126 we read "The expression sizeof(object) yields an integer equal to the size of the specified object. ... The object can be an acutual variable or array or structure, ..." I don't see anything here about other expressions. The confusion seems to be over the reference manual which indicates that the grammar will accept "sizeof expression" syntactically. This is obviously a shortcut for the compiler writer(s). However, the semantic interpretation is explained above(p.126). All this is quite true, and I was aware of page 126. But the definition of the language is the C Reference Manual, ***NOT*** the textbook that happens to precede one particular edition of it. All page 126 tells us is what DMR *intended*, but that's been clear all along anyway. -- Henry Spencer @ U of Toronto Zoology {allegra,ihnp4,linus,decvax}!utzoo!henry
ado@elsie.UUCP (06/16/84)
Here are additions to "/usr/src/cmd/mip/trees.c" (as distributed with 4.1bsd)
to detect side effects inside sizeof and issue a warning.
Since the usual licensing restrictions apply, I'll be vague.
1. After the declarations in a function named "doszof", add these lines:
#ifndef OLDVERSION
if (haseffects(p))
werror( "operations in object of sizeof are skipped" );
#endif
2. Right after the function names "doszof", add these lines:
#ifndef OLDVERSION
static int haseffects(p)
register NODE * p;
{
register o, ty;
o = p->in.op;
ty = optype(o);
if (ty == LTYPE)
return 0;
if (asgop(o) || callop(o))
return 1;
if (haseffects(p->in.left))
return 1;
if (ty == UTYPE)
return 0;
return haseffects(p->in.right);
}
#endif
If you're truly into portability, you can arrange for something more severe than
a warning.
--
...decvax!allegra!umcp-cs!elsie!ado (301) 496-5688
EGADS! All these months of giving an address that includes "decvax" and
I've failed to always note that the VAX in decvax is a Digital Equipment
Corporation trademark. Please, DEC, hold off on the lawsuit--I plan to reform.
henry@utzoo.UUCP (Henry Spencer) (06/20/84)
I fully agree that my side-effects-of-sizeof program was an abomination, and I wasn't "grumbling" about the second printf producing a "1" so much as I was grumbling about the fact that the manual doesn't actually permit this (eminently sensible) behavior. The compilers are *not* broken, the manual is. I'm told that the draft ANSI C standard now includes specific words to the effect that sizeof is fully compile-time and side effects don't occur. Good. -- Henry Spencer @ U of Toronto Zoology {allegra,ihnp4,linus,decvax}!utzoo!henry
addw@root44.UUCP (Alain Williams) (06/28/84)
<<<<<To be eaten by mailers>>>>> Henry Spencer @ U of Toronto Zoology produced the following abomination: main(){ int x = 1; printf("%u\n", sizeof(x++)); printf("%d\n", x); } He grumbles that the second printf produces a result of "1", & comments: >> But nowhere in K&R is there anything that would >> permit this wanton disregard of side effects, But there is "nowhere in K&R is there anything that would" suggest that the compilers are to be proof against all idiots. If one tries hard enough it is possible to find pathological cases that break almost anything. Indulging in such exercises is something that I enjoyed as an undergraduate, but have since grown out of. I now try & USE the tools that I have. Alain Williams, Root Computers Ltd, London. {ENGLAND}!hirst1!root44!addw edai!root44!rootis!addw ukc!root44!addw