Re: Urgent C Questions
- From: John Bode <john_bode@xxxxxxxxxxx>
- Date: Wed, 16 Jan 2008 12:05:50 -0800 (PST)
On Jan 15, 8:57 pm, Hans Schneider <h...@xxxxxxxxxxxxxxxxxxxxx> wrote:
Jack Klein schrieb:
On Tue, 15 Jan 2008 03:41:56 +0100 (CET), Hans Schneider
<h...@xxxxxxxxxxxxxxxxxxxxx> wrote in comp.lang.c:
For it to be a C question, urgent or not, it would have to be about
valid C code.
1. in the prg bellow what vars are stored on stack, heap, data segment?
int i;
void main()
The line above generates undefined behavior, not valid C code.
3. what is the o/p of this prg?
void main()
The line above generates undefined behavior, not valid C code.
I didn't write this code, but what is wrong about it?
In 'C: the complete reference' all prgs start like that.
And they're all wrong. Schildt is infamous for getting basic concepts
wrong and teaching bad habits. He's living proof that you don't need
to know what you're talking about to be considered an "expert".
The problem is that the language standard requires main() to return
int, not void. Typing main() to return void invokes undefined
behavior, which means the compiler is under no obligation to generate
correct or meaningful code. One compiler allegedly launched Rogue
when it encountered undefined behavior. In practical terms, the
calling conventions for a void function may differ significantly from
those for an int function, meaning the machine code generated will be
different. Depending on the platform, a program using void main() may
crash on exit; it may not even load at all. For most common
platforms, it may appear that there are no problems with void main(),
but appearances are not guarantees.
If you're using "C: The Complete Reference" as your primary resource,
throw it in the trash and get something better, like Kernighan &
Ritchie's "The C Programming Language".
{
int x = 5;
x = x++;
The line above generates undefined behavior, not valid C code.
Is x++ not the same as x=x+1?
It is, but "x = x++;" is not. Use just "x++;".
"x = x++" invokes undefined behavior, because x is being modified more
than once between sequence points.
printf("x=%i", x);
Since there is no prototype for printf() in scope, this causes
undefined behavior, not valid C code.
QuickC didn't complain.
Then you need to turn up the warning level on QuickC.
lcc-win32 prints lots of warnings.
Warning test.c: 3 old-style function definition for 'main'
Warning test.c: 3 missing prototype for 'main'
Warning test.c: 3 'void main()' is a non-ANSI definition
Warning test.c: 6 missing prototype for printf
Warning test.c: 6 Missing prototype for 'printf'
0 errors, 5 warnings
What do they mean?
The first three warnings have to do with how you declared main().
Going in reverse order:
Warning test.c: 3 'void main()' is a non-ANSI definition
The language standard mandates two definitions for main():
int main(void)
int main(int argc, char **argv) /* or char *argv[] */
Note that in both cases, main() returns int. This is mandated by the
language standard, and typing main() to return anything else results
in undefined behavior. Note that an individual implementation *may*
support other definitions for main() (and in a freestanding
implementation, all bets are off), but more often than not, the two
definitions above are it.
Warning test.c: 3 missing prototype for 'main'
The 1989/1990 revision of the language (known around here as C89 or
C90) added the concept of prototypes to function declarations and
definitions. Pre-C89, function declarations only specified the
function name and return type, and function definitions specified the
number of parameters, but not their types:
/* old-style function declaration */
double foo();
/* old-style function definition */
double foo(a, b, c)
double a;
int b;
char *c;
{
/* code for foo */
}
With prototypes (or more precisely, prototype syntax), you specify the
number *and types* of the parameters in both the declaration and
definition:
/* function declaration with prototype syntax */
double foo(double a, int b, char *c);
/* function definition with prototype syntax */
double foo(double a, int b, char *c)
{
/* code for foo */
}
For functions that take no parameters, the keyword void is used as the
parameter list:
/* bar takes no arguments */
int bar(void);
This enhancement allowed compilers to do a better job of detecting
mismatches between function calls definitions and function definitions
(wrong number or types of parameters). It also handled issues with
type promotions, but that's a subject for another day.
Warning test.c: 3 old-style function definition for 'main'
I think this is just a repeat of not using prototype syntax, but Jacob
would have to confirm that.
Why are there 2 warnings on line 6?
Some of them go away with #include <stdio.h>.
stdio.h contains the declaration (in prototype syntax) for printf():
int printf(const char *fmt, ...);
If the C compiler sees a function call before it sees a prototype for
that function (either a declaration or a definition), it assumes that
the function returns int and takes an unspecified number of
parameters, *as though* it had been declared
int f();
The two warnings look redundant to me (again, Jacob would have to
clarify what's going on there), but they basically refer to the fact
that you have called a function without first providing a declaration
or a definition for it.
But where is the prototype for main()?
There's no separate declaration for main(); the prototype is in the
definition:
int main(void)
{
/* code for main */
}
Again, the term "prototype" refers to including the types of each
parameter in the parameter list for both function declarations and
definitions.
}
(I think it shoulld be printing 5 but it prints 6!)
I think it should print, "This code was written by an idiot!".
With MS QuickC and GCC it prints 6.
With lcc-win32 it prints 5.
But gcc says 'operation on x may be undefined'.
I'll have to investigate why.
You've been told the answer: x = x++; invokes undefined behavior. The
expression attempts to modify x more than once between sequence points
(that is, points in the execution of the code where all side effects
have been evaluated). Both the '=' and '++' operators have side
affects (in the expression above, modifying x). Since the behavior is
undefined, the compiler is free to do whatever it wants; there is no
correct result (or, canonically speaking, *any* result is considered
correct).
Note that a statement like "i = j++;" is well-defined, because you're
not attempting to modify the same object more than once.
ps: I am using QuickC 2.0
pps: Is very urgent!
Sorry, non of these is a question about the C language. If you are in
an actual C programming course, and your instructor asked these
questions for a homework assignment, do the following:
1. Immediately drop the class.
I can't!
It is required for an advanced class.
2. Complain to the school administration about the unqualified
instructor and erroneous material.
I don't think that's gonna work.
He is a cousin of the principal.
Then defend yourself and get *good* C references (in addition to
Kernighan and Ritchie, there's also "C: A Reference Manual" by
Harbison & Steele, currently 5th ed.). No reference is perfect, but
those two are among the best.
.
- References:
- Urgent C Questions
- From: Hans Schneider
- Re: Urgent C Questions
- From: Jack Klein
- Re: Urgent C Questions
- From: Hans Schneider
- Urgent C Questions
- Prev by Date: Re: writing alarm function
- Next by Date: Re: Urgent C Questions
- Previous by thread: Re: Urgent C Questions
- Next by thread: Re: Urgent C Questions
- Index(es):
Relevant Pages
|