andrew clarke <[EMAIL PROTECTED]> wrote:
> Simion Stoilow wrote:
> > While running the following code I was surprised to see a
> > different result from the one I expected:
C is the _WRONG_ language to learn by experimentation!!
Never write a line of code unless you know exactly what it
does!
> > int a = 10;
> > double b = 5;
> > int sz_ret = sizeof (a>b? a:b);
Better would be...
size_t sz_ret = sizeof (a>b? a:b);
> > In this case, while (to me) the obvious result would have
> > been sz_ret = 4 (as the result of the exp 'a>b? a:b' is a)
> > after running this code under VS6 sz_ret = 8.
Do not presume that sizeof(int) and sizeof(double) are the
same for everyone. As Paul Herring states, sizeof is evaluated
at compile time. The only exception is when it is applied to
C99's variable length arrays.
Note that apart from the mentioned exception, expression operands
of sizeof are never evaluated. Only their type is important.
For instance, the following is quite legal...
int *ip = NULL;
size_t sz = sizeof *ip;
It will put sizeof(int) into sz, even though would be undefined
behaviour to actually evaluate *ip as it is a null pointer.
> > Any reason for this behavior?
>
> The comparison of 'a' with 'b' requires the compiler to
> implicitly typecast 'a' to a double.
It requires an implicit conversion in accordance with
usual arithmetic promotion, yes.
> The ?: ternary operator then uses this value
> as the return result.
No. The _type_ of (1.3 < 2 ? 1 : 0) is int, even though a
double is involved in condition expression.
For (e1 ? e2 : e3), what matters is the type of e2 and e3.
Integral promotion and the usual arithmetic promotions are
applied if applicable.
For instance, the expression (1 < 0.0 ? 1u : -1) is of type
unsigned int, even though the condition fails and -1 is the
notional result. Since the expressions have type unsigned
int and int respectively, unsigned int is preferred. The
result value is converted to that type and UINT_MAX is
produced!
Really good compilers may even warn you about this...
% type cmp.c
#include <stdio.h>
int main(void)
{
if ((1 < 0.0 ? 1u : -1) < 0)
puts("negative");
return 0;
}
% acc cmp.c
cmp.c: In function `main':
cmp.c:5: warning: signed and unsigned type in conditional
expression
cmp.c:5: warning: comparison of unsigned expression < 0 is
always false
--
Peter