home *** CD-ROM | disk | FTP | other *** search
- Path: sparky!uunet!olivea!charnel!sifon!thunder.mcrcim.mcgill.edu!mouse
- From: mouse@thunder.mcrcim.mcgill.edu (der Mouse)
- Newsgroups: comp.lang.c
- Subject: Re: Question to test general C knowledge
- Message-ID: <1992Dec12.230520.771@thunder.mcrcim.mcgill.edu>
- Date: 12 Dec 92 23:05:20 GMT
- References: <Bz0A46.Cvu@watserv1.uwaterloo.ca> <19980@ksr.com> <1992Dec11.180939.20726@crd.ge.com>
- Organization: McGill Research Centre for Intelligent Machines
- Lines: 76
-
- In article <1992Dec11.180939.20726@crd.ge.com>, volpe@bart.NoSubdomain.NoDomain (Christopher R Volpe) writes:
- > In article <1992Dec11.091819.26636@thunder.mcrcim.mcgill.edu>, mouse@thunder.mcrcim.mcgill.edu (der Mouse) writes:
- >> In article <19980@ksr.com>, jfw@ksr.com (John F. Woods) writes:
-
- >>> int i = 2;
- >>> i = ++i;
- >> "Anything or nothing. 3 seems most probable, with 4 next."
- > ^^^^^^^^^^^^
- > Why?
-
- Based on a sequence like
-
- ! compute needed values
- addl3 _i,$1,r0 ! compute value of ++i
- ! sequence point; do accumulated side-effects
- movl r0,_i ! store value of ++i into i
- incl _i ! increment i
-
- Thus we see the wisdom of ANSI's rule :-)
-
- > The effect of the "++" is to assign 3 to i.
-
- The effect of the ++ is to increment i. Whether this results in
- assigning 3 to it depends on whether it still has the value 2 when the
- increment gets around to happening.
-
- > (Other than, of course, a vindictive compiler that detected
- > violations of the letter of the law and went out of its way to give
- > you garbage.)
-
- I have often wished that compilers had a flag that said "please be as
- perverse as you can and break as many invalid assumptions as you can",
- as an aid to bug-finding. gcc with loads of warnings turned on is
- fairly good at finding invalid code, but there are some things that it
- by its nature can't do. For example,
-
- double sqrt(double);
- int isqrt(int);
-
- struct {
- char *name;
- int type;
- #define T_D_D 1 /* double xxx(double) */
- #define T_I_I 2 /* int xxx(int) */
- void (*fn)(void);
- } optable[] = { { "sqrt", T_D_D, (void (*)(void)) sqrt },
- { "isqrt", T_I_I, (void (*)(void)) isqrt },
- ....
- { 0 } };
- ....
- for (i=0;optable[i].name;i++)
- { if (!strcmp(optable[i].name,opname))
- { switch (optable[i].type)
- { case T_D_D:
- push_result( TYPE_DOUBLE,
- (*(double (*)(double))optable[i].fn)
- (*(double *)pop_value()) );
- break;
- case T_I_I:
- push_result( TYPE_INTEGER,
- (*(double (*)(double))optable[i].fn)
- (*(double *)pop_value()) );
- break;
- ....
-
- Now, the T_I_I case is broken: the casts should be (int (*)(int)) and
- (int *). But the compiler is required to accept the code anyway; it
- takes run-time checking to catch this. (This is not real code, but
- very similar code is likely to exist in interpreters of some sorts.)
- Nonetheless, on some systems, it may work anyway because doubles are
- passed and returned in ways similar to those use for ints....
-
- der Mouse
-
- mouse@larry.mcrcim.mcgill.edu
-