Nerox wrote On 09/21/05 17:03,:
Hi, If i write:
#include <stdio.h>
int foo(int);
int main(void){
int a = 3;
foo(a);
}
int foo(int n){
n > 10 ? return 1 : return 0;
}
This code yields a compilation error, but if i write:
return n > 10 ? 1 : 0;
instead, it works. Why?
What does the standard say about that?
You have not understood the distinction between
"statements" and "expressions" in C. A "statement" can be
understood as an imperative: test a value with `if' and take
different execution paths depending on whether the value is
zero or not, repeat a section of code `while' a value is non-
zero, and so on. One of these imperatives is `return', which
tells C to cease executing the current function and resume
executing its caller, and may also pass a value back so the
caller can use it. The two forms of the imperative `return'
statement are
return;
return _expression_;
.... where the first form simply returns to the caller,
and the second also passes back the value of _expression_.
`n > 10 ? 1 : 0' is the _expression_ in your second
example, and "it works" because this is one of the two
permitted forms of the `return' statement.
An "expression" is a sequence of one or more operands
and zero or more operators, combined according to the
rules of the language. Expressions are not imperative in
the way statements are: they describe a computation that
produces a value, but say very little about how the value
is derived. For example, the expression `f(x) + g(y)'
produces a value that is the sum of `f(x)' and `g(y)', but
doesn't say whether to evaluate `f(x)' before or after
`g(y)'. It just describes the desired value and lets the
compiler figure out how to derive it.
So: can `return' be part of an expression? No, because
it is not an operand and it is not an operator: it makes
exactly as much sense as trying to put `for' or `goto' in
the middle of an expression, to wit, no sense at all. (Not
in C, anyhow; some languages do not distinguish so sharply
between expressions and statements). That's why your first
form yields a compilation error: you've written something
that looks a little bit like an expression, but contains
things that can't appear in expressions.
One source of confusion is that an expression plus a
semicolon can be used wherever a statement is permitted;
this usage is called an "expression statement." When you
see something like `x = 42;' it's tempting to think of it
as an "assignment statement," but it's really an expression
statement made from the expression `x = 42' and the `;'.
The expression happens to contain the assignment operator
`=', and the value produced by the expression (yes, it
produces one) is ignored, but it's really just an ordinary
expression, evaluated in order to achieve the side-effect
of storing a new value in `x'. Some other languages handle
assignment differently: original BASIC, for example, used
`LET X = 42'. In such languages the `=' or `:=' or whatever
is part of the punctuation of the assignment statement (the
way parentheses are part of the punctuation of `while'), but
in C the `=' is a full-fledged operator.
Here are a few more expression statements for you to
ponder -- if you think carefully, you'll realize that they
are all merely expressions and not imperatives, and that
they are all evaluated merely for their side-effects:
++i;
printf("Hello, world!\n");
p = malloc(sizeof *p);
free(p);
The fourth is different from the others in a subtle way.
The first three expressions all produce values that are
ignored: the value of the first is the new value given to
`i', that of the second is the number of characters written
(or EOF if there was an I/O error), that of the third is
the value assigned to `p'. But the fourth produces no value
at all. Some languages distinguish between "functions" that
return values and "subroutines" that do not, but in C there
is no such distinction. Formally (and somewhat artificially)
speaking, the `free' function actually does declare the type
of value it returns -- but that type is `void', and the only
thing you can do with a `void' value is ignore it. This
vacuous `void' type lets C "regularize" itself, in a sense.
Instead of having parallel sets of rules for expressions that
do and don't produce values, C uses just one set of rules and
says that all expressions produce values -- but that some of
the produced values are `void'. (It's reminiscent of a legal
decision some years ago: the court held that an employer's
medical insurance plan did not discriminate against female
employees by failing to provide pregnancy benefits, because
the plan also denied pregnancy benefits to men and thus
treated both sexes equally.)
Summary: Although any expression can be turned into a
statement by appending a `;', no statement can appear as part
of an expression. An expression always produces a value (in
some cases a `void'), but a statement never produces a value
(not even a `void' one).
--
Er*********@sun.com