Need some explanation

C

Chris Hills

Mark McIntyre said:
main must return an int - void main() is illegal C code.

Main only returns int in a hosted environment.

In free stranding environments there is nothing to return to. So

void main()

Is the only practical real world solution (and quite legal). The entry
point to the C program does not *have* to be called main but for the
majority of debugging tools it needs to be.
 
M

Mark McIntyre

It isn't 'illegal'

Illegal is CLC shorthand for "disallowed by the C standard" as I'm
sure you well know.
(the only place that word is used in the standard is
in the context of an "illegal instruction" raising a signal). It is
implementation defined whether it is permitted in a hosted environment;

This is a very old topic of discussion. The C99 standard requires main
to return an int in a hosted environment. There's no implementation
defined-ness about it, and I believe its now widely agreed that the
final phrase of 5.1.2.2.1 (1) refers to the arguments of main.
 
M

Mark McIntyre

Main only returns int in a hosted environment.

In free stranding environments there is nothing to return to

Absolutely. Was the OP writing for a freestanding implementation?

I also note for reference that discussion of freestanding
implementations is generally regarded as offtopic here (or at least
largely pointless), since there are few requirements placed on such
implementations by the standard.

So
 
C

Chris Croughton

Cryptography, DVD decoders, viruses...

No, those are applications and can be written in any language. I'm
referring to C code itself, like making it a criminal offence to use
goto or break...

Chris C
 
C

Chris Croughton

Good luck on your campaign to get programmers to speak English. You
should not expect quick results.

Indeed, even getting them to speak American would be hard <g>...

Chris C
 
C

Chris Croughton

Main only returns int in a hosted environment.

In free stranding

Is that like lightweight threads? said:
environments there is nothing to return to. So

void main()

Is the only practical real world solution (and quite legal). The entry
point to the C program does not *have* to be called main but for the
majority of debugging tools it needs to be.

I don't think I've come across an embedded debugging tool which cared
what the entry point is called, they seem to only need to know the start
address (if that isn't hardwired by the processor). Certainly the
mobile phone systems I've programmed at that level have had all sorts of
names for the entry point (boot, entry, startup, etc.) at a whim of the
original programmer or designer.

However, there are probably loads of debuggers I haven't used, every
processor manufacture seems to have their own favourites...

Chris C
 
C

Chris Hills

Mark McIntyre said:
Absolutely. Was the OP writing for a freestanding implementation?

I also note for reference that discussion of freestanding
implementations is generally regarded as offtopic here (or at least
largely pointless), since there are few requirements placed on such
implementations by the standard.

However there are probably as many free standing implementations as
hosted. Besides who is the authority to say half the C world is off
topic in a C language group.

However I take your point that in SOME areas the freestanding
implementation is unspecified or implementation defined
 
S

S.Tobias

Mark McIntyre said:
This is a very old topic of discussion. The C99 standard requires main
^^^^^
to return an int in a hosted environment.

Would you please explain this to me, or give me some pointers
to past discussions where I could read about this myself?

I did google a bit, and found no proof of your assertion.
In fact, opinions on this (coming from the top clc gurus)
varied both ways.
 
R

Richard Heathfield

S.Tobias said:
Would you please explain this to me,

Well, if you want your program to be portable, you have to return int.
Implementations are allowed to define behaviours for alternative return
types for main (they were in C90 too, but C99 merely makes this explicit),
so you can argue that void main is implementation-defined, but ONLY for
implementations that define it! In other implementations, it remains
undefined, and so it's not unreasonable to argue that the C99 standard
requires programs-intended-to-be-portable to return int.
or give me some pointers
to past discussions where I could read about this myself?

Pick 20 articles at random from comp.lang.c's archives. I should think that
at least 6 of them will be about void main.

I did google a bit, and found no proof of your assertion.
In fact, opinions on this (coming from the top clc gurus)
varied both ways.

The safe thing to do is go with int main, unless your implementation
actually forbids it (eg freestanding).
 
L

leeaby

hello,
1) First how following program get executed i mean how output is
printed and also why following program gives different output in Turbo
C++ compiler and Visual c++ 6 compiler?
void main()
{
int val=5;
printf("%d %d %d %d",val,--val,++val,val--);
}
under turbo compiler its giving
4 4 5 5

This is because turbo compiler executes such single line code from
right to left.
i.e., val-- gets first evaluated, next ++val and so on.
val -- prints a '5'(the value of variable val),substract value of 'val'
by 1, so that now val=4
Now ++val gets executed, ++ before val increments val before printing,
so you obtain a '5'.Now val=5
After this -- val gets executed, substracting 1 from val before
printing as said before and you get a '4' at the output.At this point
val=4
So finally val gets printed and you obtain the current value of the
'val' to be 4

It should be noted that though execution takes place from right to
left, printing takes place in the order defined in printf

It should also be noted that void main() is not a good practice, better
use int main() along with a return 0; just before you end the main()
 
S

S.Tobias

Richard Heathfield said:
Well, if you want your program to be portable, you have to return int.

Oh, please! I didn't ask about portability! Mark McIntyre made
a rather bold assertion that C99 forbids non-int main, and I asked
only about that.
Implementations are allowed to define behaviours for alternative return
types for main

So can I assume that you disagree now with Mark here?
(they were in C90 too,

I don't think so, C90 allowed only two forms, both returning int.
but C99 merely makes this explicit),
so you can argue that void main is implementation-defined, but ONLY for
implementations that define it!

Well, yes, that's exactly what implementation-defined means, doesn't it?
(Everything after "but" is redundant.)
In other implementations, it remains
undefined,

If it's not defined, then it's undefined, sure.
and so it's not unreasonable to argue that the C99 standard
requires programs-intended-to-be-portable to return int.

Yes, and those programs are called "strictly conforming". However
the Standard does not preclude non-portable conforming programs
(Annex J.3 is a guide how to write them).
Pick 20 articles at random from comp.lang.c's archives. I should think that
at least 6 of them will be about void main.

Mostly people bashing other people for using non-portable `void main'.
I was looking for some valid arguments why `non-int main' should be
forbidden by C99, and have found none (maybe I haven't searched enough).

The discussions I found were mostly from 2000-2002. Among them you
claiming (citing from my memory) that "the Std never did, and never
will allow `void main'"; one post from Jack Klein saying `void main'
is disallowed in C99. Two (unrelated) posts from Dan Pop explaining that
`void main' is allowed provided that the implementation documents it.
And numerous other people that seemed important and had different
opinions.
The safe thing to do is go with int main, unless your implementation
actually forbids it (eg freestanding).

My question was not about portability, and obviously concerned only
a hosted implementation.

Could you comment on my point of view below. I'm not trying to cover
all `main' issues, just things relevant to this discussion.


C90 disallowed `non-int main' (only two forms were allowed).
Implementations that accepted other forms were not conforming.

C99 allows other (non-portable) forms, provided that the implementation
documents them. For example:
float _Complex main(int n, _Bool [restrict static 10][n],
struct { float _Imaginary im; long long fam[]; } *,
...);
(Yes, that's an ellipsis - why not?)

The exit status is meaningful only when the return type is compatible
with the type `int'.
Arguments `argc' and `argv' have their meaning only when main is
defined as "int main(int argc, char **argv)". Otherwise they haven't:
int main(int argc, char **argv, char **envp)
void main(int argc, char **argv)
In neither of above cases need `argc' and `argv' have their usual
meaning and constraints.

What changed between C90 and C99 is that what was an extension in C90,
can now be allowed, ie. a compiler does not cease to be conforming
when it accepts other (documented) forms of `main'. It's not meaningful
to anyone, but implementors.
What C90 and C99 have in common is that `main' is the function that
starts the program, and returning from the first instance finishes it.
 
R

Richard Heathfield

S.Tobias said:
Oh, please! I didn't ask about portability! Mark McIntyre made
a rather bold assertion that C99 forbids non-int main, and I asked
only about that.

My interest is in clarifying the facts, not in settling disputes.
So can I assume that you disagree now with Mark here?

You can assume that implementations are allowed to define behaviours for
alternative types for main.
I don't think so, C90 allowed only two forms, both returning int.

C90 allows any implementation to provide extensions to the language.

"A conforming implementation may have extensions (including additional
library functions), provided they do not alter the behavior of any strictly
conforming program."

A strictly conforming program would not be affected by an implementation's
support for void main.
Well, yes, that's exactly what implementation-defined means, doesn't it?
(Everything after "but" is redundant.)

Well, yes and no.

* Implementation-defined behavior --- behavior, for a correct program
construct and correct data, that depends on the characteristics of the
implementation and that each implementation shall document.

void main is not implementation-defined, because implementations are not
required to document void main. Rather, implementations are free to provide
extensions such as void main, provided they document them. (And, of course,
if they choose not to document them, they simply become extensions anyway.)

So nothing has changed in C99. A void main program still works some places,
and not others.

If it's not defined, then it's undefined, sure.

Quite so.
Yes, and those programs are called "strictly conforming".

Well, I wouldn't claim strict conformance for most of the programs I've
written that were intended to be portable. I'm not that brave.
However
the Standard does not preclude non-portable conforming programs
(Annex J.3 is a guide how to write them).

Fortran programs are conforming C programs. (They are acceptable to gcc,
which is a conforming implementation.) So the term "conforming program" is
not terribly useful.

My question was not about portability, and obviously concerned only
a hosted implementation.

Then you must consult your documentation. If your C99 implementation (a)
exists!, and (b) documents void main, then void main is "legal" for that
implementation, but that "legality" is non-transferable.
Could you comment on my point of view below. I'm not trying to cover
all `main' issues, just things relevant to this discussion.


C90 disallowed `non-int main' (only two forms were allowed).
Implementations that accepted other forms were not conforming.

No, the behaviour is undefined, so the compiler can do anything it likes,
including accepting the program and doing something reasonable. Bear in
mind that void main is neither a syntax error nor a constraint violation,
so no diagnostic is required. (Better compilers do, however, diagnose
this.)
C99 allows other (non-portable) forms, provided that the implementation
documents them. For example:
float _Complex main(int n, _Bool [restrict static 10][n],
struct { float _Imaginary im; long long fam[]; } *,
...);
(Yes, that's an ellipsis - why not?)

Correct, but a C90 implementation /may/ accept such a form too.
The exit status is meaningful only when the return type is compatible
with the type `int'.
Arguments `argc' and `argv' have their meaning only when main is
defined as "int main(int argc, char **argv)". Otherwise they haven't:
int main(int argc, char **argv, char **envp)
void main(int argc, char **argv)
In neither of above cases need `argc' and `argv' have their usual
meaning and constraints.
Correct.


What changed between C90 and C99 is that what was an extension in C90,
can now be allowed, ie. a compiler does not cease to be conforming
when it accepts other (documented) forms of `main'.

Providing extensions does not make an implementation non-conforming,
provided it handles strictly conforming programs properly.
It's not meaningful
to anyone, but implementors.

There I must disagree. The reason this matters so much is that it's a
question of ownership. Who owns the main() declaration? Answer: not the
programmer! It's an <shout>interface specification</shout>, and both sides
of the interface should adhere to that spec. That's common sense.
 
K

Keith Thompson

S.Tobias said:
Well, yes, that's exactly what implementation-defined means, doesn't it?
(Everything after "but" is redundant.)

No, it's not redundant.

Consider this program:

void main(void){}

If an implementation's documentation says that void main(void) is
allowed, then the program has implementation-defined behavior on that
implementation. I can be sure that executing this program won't make
demons fly out of my nose (unless the documentation says that it can).

Suppose I try to compile the same program on another implementation,
one that doesn't document void main(void) is allowed. On that
implementation, there is no "other implementation-defined manner" as
stated in 5.1.2.2.1, so the program violates a "shall" outside a
constraint. It therefore invokes undefined behavior, which means it
*can* make demons fly out of my nose. On this implementation there's
nothing implementation-defined going on.

(It may be that the only difference between the two implementations is
their documentation. The undefined behavior on the second
implementation may happen to be the same as the implementation-defined
behavior on the first.)
 
C

CBFalconer

Richard said:
S.Tobias wrote:
.... snip ...

Providing extensions does not make an implementation non-conforming,
provided it handles strictly conforming programs properly.


There I must disagree. The reason this matters so much is that
it's a question of ownership. Who owns the main() declaration?
Answer: not the programmer! It's an <shout>interface
specification</shout>, and both sides of the interface should
adhere to that spec. That's common sense.

Tobias is missing the point that the subject of c.l.c is _portable_
C code, as defined by the standards from K&R through C89, C90, C95,
and C99. If you have to specify the implementation, you are
off-topic here.

Welcome back from your wilderness wanderings, Richard. It has
exceeded 40 days. EGN is going to be suspicious about your MI5
connections.
 
R

Richard Heathfield

CBFalconer said:
Tobias is missing the point that the subject of c.l.c is _portable_
C code, as defined by the standards from K&R through C89, C90, C95,
and C99. If you have to specify the implementation, you are
off-topic here.

He also seems to be missing the point that the Standard's introduction of
optional implementation-defined behaviour for "main() return type" is of a
different /kind/ to normal implementation-defined behaviour.
Welcome back from your wilderness wanderings, Richard. It has
exceeded 40 days.

I think this is getting needlessly Messianic.

EGN is going to be suspicious about your MI5
connections.

I've already modded him down 1000 in my newsreader, on the assumption that
he still hasn't grown up yet. If he ever does, no doubt someone will let me
know. I simply don't have the time at present to indulge in that kind of
nonsense. The man is a sink for all kinds of resources: time, energy,
bandwidth, disk space (for those who archive), and - not least - patience.
I'd rather use those resources in more constructive ways.
 
S

S.Tobias

Richard Heathfield said:
Well, yes and no.

* Implementation-defined behavior --- behavior, for a correct program
construct and correct data, that depends on the characteristics of the
implementation and that each implementation shall document.

void main is not implementation-defined, because implementations are not
required to document void main. Rather, implementations are free to provide
extensions such as void main, provided they document them. (And, of course,
if they choose not to document them, they simply become extensions anyway.)

I think I see what you mean. Other `main' forms are "optionally
implementation defined". (It is not even impl-defined _whether_ an
implementation defines alternative `main's, because implementations
are not required to document that, right?)
I was thinking more-or-less along these lines, but thanks for clarification.
Providing extensions does not make an implementation non-conforming,
provided it handles strictly conforming programs properly.

Thank you, I was confused about what "conforming implementation" meant.

So what really changed is that the implementors may now move their
chapter "Accepted `main' forms" from "Extensions" to the part
called "Implementation-defined features"?
There I must disagree. The reason this matters so much is that it's a
question of ownership. Who owns the main() declaration? Answer: not the
programmer! It's an <shout>interface specification</shout>, and both sides
of the interface should adhere to that spec. That's common sense.

I don't quite understand what you've said and why. What I meant is
that the change in C99 is not very interesting for the programmers
(clients), because whether `void main' is an extension or implementation
defined feature, I still have to find and check it in the missing compiler
documentation (or write one myself). It seems that even implementors
are not affected by the change very much.


So can this discussion be finished with the following conclusion:

Neither C90 nor C99 forbid other `main' forms (including non-int
`main's). They just don't define them, which means that those forms
don't belong to ISO C, and are forbidden in strictly conforming
programs (and writing them in c.l.c is a criminal offence).

In particular, the assertion "the final phrase of 5.1.2.2.1 (1) refers
only to the arguments of main" is false.
 
C

Chris Hills

CBFalconer said:
Tobias is missing the point that the subject of c.l.c is _portable_
C code, as defined by the standards from K&R through C89, C90, C95,
and C99. If you have to specify the implementation, you are
off-topic here.

Does it say that in the charter for this NG?
 
S

S.Tobias

Chris Hills said:
My questions concerned only the scope of the C Standard (what
it defines, allows and forbids). I don't see how they can be
off-topic here (perhaps c.s.c would be better, but the problem
I wanted to discuss started here).
I have never advocated use of non-portable code.

Besides that, IMHO C doesn't give portability for free, and in order
to write portable programs you have to know what is not portable.
I think questions on what code is non-portable and why, belong
here, too.
Does it say that in the charter for this NG?

It has never been an argument for me.
 
K

Keith Thompson

S.Tobias said:
I think I see what you mean. Other `main' forms are "optionally
implementation defined". (It is not even impl-defined _whether_ an
implementation defines alternative `main's, because implementations
are not required to document that, right?)
I was thinking more-or-less along these lines, but thanks for clarification.

I think your parenthesized statement is incorrect. Each
implementation either does or does not document that it accepts void
main(). If it doesn't document it, it's not implementation-defined
for that implementation; if it does, it is.

An implementation is not required to document that it *doesn't*
support void main. (If it implements it without documenting it, then
a program using void main invokes undefined behavior; documenting what
that behavior is makes it implementation-defined.)

[...]
So can this discussion be finished with the following conclusion:

Neither C90 nor C99 forbid other `main' forms (including non-int
`main's). They just don't define them, which means that those forms
don't belong to ISO C, and are forbidden in strictly conforming
programs (and writing them in c.l.c is a criminal offence).

Agreed (though "criminal" is a bit overstated).
In particular, the assertion "the final phrase of 5.1.2.2.1 (1) refers
only to the arguments of main" is false.

That's still an interesting point. Here's what the standard says:

The function called at program startup is named main. The
implementation declares no prototype for this function. It shall
be defined with a return type of int and with no parameters:

int main(void) { /* ... */ }

or with two parameters (referred to here as argc and argv, though
any names may be used, as they are local to the function in which
they are declared):

int main(int argc, char *argv[]) { /* ... */ }

or equivalent; or in some other implementation-defined manner.

I find the wording ambiguous; the interpretation depends on how the
phrases are grouped. There are three options:

(1) return type of int and no parameters;
(2) ... two parameters;
(3) ... some other implementation-defined manner.

The phrase "return type of int" does not appear explicitly in choice
2, but we know it's required because we're shown the declaration. The
structure of the sentence implies that the "return type of int" is
also implicit in the third choice. In other words, the sentence
can be parsed as:

return type of int and
(1) no parameters;
(2) two parameters;
(3) some other implementation-defined manner.

I don't *think* that was the intent; in particular, I think the
standard intends to allow an implementation to support void main(void)
(but only if it documents it). This is confirmed by 5.1.2.2.3, which
starts with:

If the return type of the main function is a type compatible with
int,

which wouldn't make any sense if the type were required to be
compatible with int.

So I think the intent is clear, but only with more analysis than
should be necessary. I'd like to see the wording cleaned up a bit,
but that's an issue for comp.std.c, not for comp.lang.c.
 
R

Richard Heathfield

S.Tobias said:
I think I see what you mean. Other `main' forms are "optionally
implementation defined". (It is not even impl-defined _whether_ an
implementation defines alternative `main's, because implementations
are not required to document that, right?)
I was thinking more-or-less along these lines, but thanks for
clarification.

See Keith's reply for even more clarification.

What I meant is
that the change in C99 is not very interesting for the programmers
(clients),

This is certainly true, at least for as long as it takes to make C99
sufficiently portable to be worth programming for. (I generally program in
a subset of C90 and C99, so my programs are C99-ready but not
C99-dependent.)
because whether `void main' is an extension or implementation
defined feature, I still have to find and check it in the missing compiler
documentation (or write one myself). It seems that even implementors
are not affected by the change very much.

The change is even less interesting for those of us who simply use the
canonical form of main.
So can this discussion be finished with the following conclusion:

Neither C90 nor C99 forbid other `main' forms (including non-int
`main's). They just don't define them, which means that those forms
don't belong to ISO C, and are forbidden in strictly conforming
programs (and writing them in c.l.c is a criminal offence).

It isn't so much that they're forbidden in strictly conforming programs, any
more than you're forbidden from scribbling graffiti on a blank wall (if you
own the wall). But once you've done it, the wall isn't blank any more.
Likewise, strictly-conforming + void main -> not strictly-conforming.

Far too much is written on the subject of void main. This is really simple
to get right - even the most trivial reading of the Standard shows that an
int return type is the natural choice for C programs that are intended to
be portable, so why not just use int?
In particular, the assertion "the final phrase of 5.1.2.2.1 (1) refers
only to the arguments of main" is false.

Keith dealt with this bit, too.
 

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

No members online now.

Forum statistics

Threads
473,774
Messages
2,569,598
Members
45,157
Latest member
MercedesE4
Top