(Info) Test Your C Programming Strengths

L

Leor Zolman

I have often wondered where not only newbies, but book authors, got the
idea that void main() was any form of C at all. As you and Richard
correctly say, void main() was never used in any form of standard C,
and it wasn't used in K&R C either. (They simply used main().) Have
those people invented it out of thin air and then started convincing
themselves it was standard C?

Having been around C for a while, it doesn't seem like much of a
mystery to me how "void main" would have come into common use
(although I'd agree there's no excuse for thinking it was
"standard")... When void was introduced into the language, it finally
provided a way to define main() in a way that means "I'm not returning
anything". This could reasonably be labeled a questionable practice on
Unix (K&R's platform, where it is always trivial to test a process's
exit status one way or another from shell script or system calls).
However, just look at the hoops DOS batch files have always made
folks jump through in order to deal with an exit status. How many
people really understand how ERRORLEVEL works, or bother with it once
they learn? It makes sense in that context to "formally" inform people
reading the source code that they are off the hook WRT the exit status
of that program...and defining main to return void seems like a pretty
straightforward way to say that.

Another point in "void main"'s favor is simple consistency; if every
other function not returning anything can be declared with void, why
single out main to the contrary? Sure, we're talking about a
"different kind of return", but can you _imagine_ how that might not
sit well with folks learning C?

Time marches on, now in strict mode it's an error. That's fine with
me. As for anyone playing "C teacher" who uses it ... I really liked
the "Be afraid" comment ... ;-)
-leor


Leor Zolman
BD Software
(e-mail address removed)
www.bdsoft.com -- On-Site Training in C/C++, Java, Perl & Unix
C++ users: Download BD Software's free STL Error Message
Decryptor at www.bdsoft.com/tools/stlfilt.html
 
L

Leor Zolman

Aplogies, group. My finger slipped while composing the message above
(in Agent, I typed control-N by accident)...the result seemed to be
that my draft was instantly posted. But I didn't know it; I thought
it was just wiped out, so wrote it over and _that_ post is below.
-leor
Leor Zolman
BD Software
(e-mail address removed)
www.bdsoft.com -- On-Site Training in C/C++, Java, Perl & Unix
C++ users: Download BD Software's free STL Error Message
Decryptor at www.bdsoft.com/tools/stlfilt.html
 
L

Leor Zolman

This does not answer the question. *WHY* would you want to make sure
everyone knew you were not returning an int? *WHY* would you not want
to return an int in the first place?

See my apology above, and my post below for the answer to that
question (which I didn't get the chance to type in the first time ;-)
-leor

Leor Zolman
BD Software
(e-mail address removed)
www.bdsoft.com -- On-Site Training in C/C++, Java, Perl & Unix
C++ users: Download BD Software's free STL Error Message
Decryptor at www.bdsoft.com/tools/stlfilt.html
 
J

Joona I Palaste

See my apology above, and my post below for the answer to that
question (which I didn't get the chance to type in the first time ;-)

So the only reason not to return an int is to make a DOS batchfile that
doesn't use ERRORLEVEL? This is still illogical. Returning an int does
not make you *use* that int, you know. It's still fully possible to
ignore the ERRORLEVEL thingies completely and *still* say within ISO
standard C code.
 
L

Leor Zolman

So the only reason not to return an int is to make a DOS batchfile that
doesn't use ERRORLEVEL? This is still illogical. Returning an int does
not make you *use* that int, you know. It's still fully possible to
ignore the ERRORLEVEL thingies completely and *still* say within ISO
standard C code.

My comments were in response to an open-ended question about how "void
main" might have come into "popular" use, and I'm describing the
situation in a time frame circa 1982-1988 (pre ANSI/ISO C). I agree
with you 100% about the situation _today_.
-leor


Leor Zolman
BD Software
(e-mail address removed)
www.bdsoft.com -- On-Site Training in C/C++, Java, Perl & Unix
C++ users: Download BD Software's free STL Error Message
Decryptor at www.bdsoft.com/tools/stlfilt.html
 
D

Default User

Thomas said:
Please get rid of those damn pop-up windows.

<OT>
That's why I embraced Mozilla as my browser (although not my newsreader,
I didn't like the way it looked). The tabbed browsing didn't hurt at
all.
</OT>




Brian Rodenborn
 
J

Jack Klein

I have often wondered where not only newbies, but book authors, got the
idea that void main() was any form of C at all. As you and Richard
correctly say, void main() was never used in any form of standard C,
and it wasn't used in K&R C either. (They simply used main().) Have
those people invented it out of thin air and then started convincing
themselves it was standard C?

Perhaps because as compilers got smarter they began to issue warnings
for functions defined "main()" that ended without a return statement,
knowing that the definition implicitly promised to return an int and
then broke the promise.

Or maybe it's just the Microsoft help files.

The latest version of Visual C++ I have used as a C compiler (6.0 bug
fix^w^w service pack ULONG_MAX) tries to amuse you when you test for
C99 conformance.

If you define:

int main()
{
/* anything except a return statement */
}

....it will tell you that you didn't return anything, and it is going
to assume that your "int" was a typo for "void".
 
J

Joona I Palaste

Perhaps because as compilers got smarter they began to issue warnings
for functions defined "main()" that ended without a return statement,
knowing that the definition implicitly promised to return an int and
then broke the promise.

Doesn't the C standard say that main() is a special case where failing
to return anything from an int function is defined behaviour?
Or maybe it's just the Microsoft help files.

Where did Microsoft get it from?
The latest version of Visual C++ I have used as a C compiler (6.0 bug
fix^w^w service pack ULONG_MAX) tries to amuse you when you test for
C99 conformance.
If you define:
int main()
{
/* anything except a return statement */
}
...it will tell you that you didn't return anything, and it is going
to assume that your "int" was a typo for "void".

Bleargh. Well, that's Microsoft for you. Give them a standard and the
first thing they do is try to break it.
 
O

Old Wolf

Click here : (url removed) to Test Your C Programming
Hm, let me try a few of those printf questions:

[Q001] - Undefined behavior, since main() must return an int.
[Q002] - Undefined behavior, since main() must return an int.
[Q003] - Undefined behavior, since main() must return an int.
[Q004] - Undefined behavior, since main() must return an int.
[Q005] - Undefined behavior, since main() must return an int.
[Q006] - Undefined behavior, since main() must return an int.

Oh well, this is getting boring. Back to work.

I've heard that the program behaviour is still defined in this case,
but its exit status is undefined (ie. the program will still do
what it is meant to do (barring any other errors!) , at least up until
after its point of termination.
 
O

Old Wolf

Doesnt' that site needs to be updated. They seem to still be using void main().
This does not answer the question. *WHY* would you want to make sure
everyone knew you were not returning an int? *WHY* would you not want
to return an int in the first place?

It's common practice (and recommended style by many) to make
functions not return a value, if the purpose of the function
does not include returning an informative value.

If one fails to understand C program startup, it's natural
to extend this practice to main().

Compounding the problem was the facts:
- most noobs use dos/windows
- the most common dos/windows noob compiler was Borland
- Borland allowed "void main()" and even included examples of it (IIRC)
 
J

Joona I Palaste

Old Wolf said:
Click here : (url removed) to Test Your C Programming
Hm, let me try a few of those printf questions:

[Q001] - Undefined behavior, since main() must return an int.
[Q002] - Undefined behavior, since main() must return an int.
[Q003] - Undefined behavior, since main() must return an int.
[Q004] - Undefined behavior, since main() must return an int.
[Q005] - Undefined behavior, since main() must return an int.
[Q006] - Undefined behavior, since main() must return an int.

Oh well, this is getting boring. Back to work.
I've heard that the program behaviour is still defined in this case,
but its exit status is undefined (ie. the program will still do
what it is meant to do (barring any other errors!) , at least up until
after its point of termination.

You've heard wrong. The ISO C standard allows a program which defines
main() as void to do *anything it bloody well wants to*, and still be
within the bounds of legal behaviour.

--
/-- Joona Palaste ([email protected]) ------------- Finland --------\
\-- http://www.helsinki.fi/~palaste --------------------- rules! --------/
"You can pick your friends, you can pick your nose, but you can't pick your
relatives."
- MAD Magazine
 
J

Joona I Palaste

It's common practice (and recommended style by many) to make
functions not return a value, if the purpose of the function
does not include returning an informative value.
If one fails to understand C program startup, it's natural
to extend this practice to main().
Compounding the problem was the facts:
- most noobs use dos/windows
- the most common dos/windows noob compiler was Borland
- Borland allowed "void main()" and even included examples of it (IIRC)

So... where did Borland get it from? Someone must have originally
invented it.
 
G

Grumble

Keith said:
I'm not surprised that there were that many errors; I'm just
surprised that you had the patience to find 1024 of them.

Obviously he used base 1, not base 2.
 
R

R. Rajesh Jeba Anbiah

Hi Friends

Click here : www.c4swimmers.esmartguy.com to Test Your C Programming
Strengths.
You can find Tricky Questions on C, Interview type queries on C,
Infrequently Answered Questions in C and many more...

Great effort. I really appreciate your hard work; you might have
sacrificed a lot to produce such a great site. I wish your site should
evolve more with lot of free and good stuffs.

By the way, you must understand the fact that C is about 30 years
old and most of the people present in this group are well experienced
C programmers/experts; few of them are even well renowned book
authors. You might have read the FAQ of this group
<http://groups.google.com/[email protected]>
So, you may consider using "humble" tone in old newsgroups like this.
(Don't mistaken me. Just my thoughts...)

All the best! Keep up your good work!
 
K

Kelsey Bjarnason

Click here : (url removed) to Test Your C Programming

Hm, let me try a few of those printf questions:

[Q001] - Undefined behavior, since main() must return an int.
[Q002] - Undefined behavior, since main() must return an int.
[Q003] - Undefined behavior, since main() must return an int.
[Q004] - Undefined behavior, since main() must return an int.
[Q005] - Undefined behavior, since main() must return an int.
[Q006] - Undefined behavior, since main() must return an int.

Oh well, this is getting boring. Back to work.

I've heard that the program behaviour is still defined in this case,
but its exit status is undefined (ie. the program will still do
what it is meant to do (barring any other errors!) , at least up until
after its point of termination.

Then your understanding is wrong. Here's a simple (albeit hypothetical)
example where void main won't work at all.

First, we assume a non-stack-based architecture. Second, we assume that
each "int function" reserves, as part of the function's lead-in, space
sufficient to store an int. Thus (in assembly pseudo) the layout of int
main() would look something like this:

..proc main
retval db 4 dup(0)
,main_code
; actual code for main starts here

Now, by declaring main as void, you end up with soemthing different:

..proc main
; actual code for main starts here

Now the problem. Since the implementation's startup code - the code that
copies the environment, mangles command-line arguments, etc, etc, etc,
before calling main - since this code knows that main returns an int,
where does it jump to when it calls main?

Right; it finds the address of main and adds 4 bytes - the size of an int
on that implementation. Except you've used void main. So the execution
starts 4 bytes into the actual code, quite possibly in the middle of an
opcode, and almost guaranteed, in any case, to produce wrong results, up
to and including crashing the program, the OS, or doing worse things - is
there any guarantee that the seqeuence of bytes stored at that address
don't mean "reformat drive 0", rather than something else?

Net result: by using void main, the program will very likely never execute
at all, or do so but incorrectly.

On the other hand, using int main() would have worked here - and on every
other conforming C compiler in existence. The obvious question would be,
then, why use something that might work, sometimes, in some cases, versus
something that will always work, if the only downside is having to
actually add a return statement in main... which, if I recall correctly,
you can even get away with leaving out in C99?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,774
Messages
2,569,598
Members
45,155
Latest member
JuliW73391
Top