Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Is 'int main() { /* ... */ }' valid?

5 views
Skip to first unread message

Keith Thompson

unread,
Jul 4, 2007, 12:08:30 AM7/4/07
to
This came out of a discussion in comp.lang.c, subject

stray"\26" in program

C99 5.1.2.2.1p1 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;9) or in some other implementation-defined manner.

Footnote 9 says:

Thus, int can be replaced by a typedef name defined as int, or the
type of argv can be written as char ** argv, and so on.

6.7.5.3p14 says:

An empty list in a function declarator that is part of a
definition of that function specifies that the function has no
parameters.

Assume an implementation that doesn't define "some other
implementation-defined manner".

So, it seems reasonable to assume that
int main() { /* ... */ }
is equivalent to
int main(void) { /* ... */ }
and is therefore legal. But does the standard actually say so?

The real question is, what is the scope if the phrase "or equivalent"?
Does it apply only to the two-parameter case, or is it intended to
apply to both the zero-parameter and two-parameter cases? As I look
at the structure of the sentence, without considering what I think it
*should* mean, I tend to think it applies only to the two-parameter
case, but I think it's ambiguous.

Note that if the "or equivalent" applies only to the two-parameter
case, then the type int can be replaced with an equivalent typedef
*only* for the two-parameter case, not for the zero-parameter case.
That seems absurd (but I've been led astray before by assuming that
the standard isn't absurd).

What is the intent? Should this be re-worded slightly to remove the
potential ambiguity? A simple fix would be to change

or with two parameters ...

to

or equivalent; or with two parameters ...

--
Keith Thompson (The_Other_Keith) ks...@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"

Rajesh S R

unread,
Jul 4, 2007, 8:03:23 AM7/4/07
to

IMHO Yes, The standards uses the phrase "with no parameters". So you
could very well have int main() and is allowed by the phrase "or
equivalent".

> The real question is, what is the scope if the phrase "or equivalent"?

I think, "equivalent" is defined in terms of semantics of the main
function declaration. "Equivalent" means that you could have any form
of declaration which have same semantics as int main(void) or int
main(int argc, char *argv[]);

> Does it apply only to the two-parameter case, or is it intended to
> apply to both the zero-parameter and two-parameter cases?

It should be applicable for both the ways of declaration.

Keith Thompson

unread,
Jul 4, 2007, 3:45:48 PM7/4/07
to
Rajesh S R <SRRaje...@gmail.com> writes:
> On Jul 4, 9:08 am, Keith Thompson <k...@mib.org> wrote:
[...]

>> The real question is, what is the scope if the phrase "or equivalent"?
>
> I think, "equivalent" is defined in terms of semantics of the main
> function declaration. "Equivalent" means that you could have any form
> of declaration which have same semantics as int main(void) or int
> main(int argc, char *argv[]);
>
>> Does it apply only to the two-parameter case, or is it intended to
>> apply to both the zero-parameter and two-parameter cases?
>
> It should be applicable for both the ways of declaration.
[...]

Ok, suppose you *wanted* the "or equivalent" to appply only to the
two-parameter case. How would you write that? It seems to me that
you could use the exact words that are currently in the standard.

Douglas A. Gwyn

unread,
Jul 5, 2007, 1:39:50 AM7/5/07
to
"Keith Thompson" <ks...@mib.org> wrote...

> The real question is, what is the scope if the phrase "or equivalent"?

No, the general issue is exemplified by

/* filea.c */
extern void foo(void);
...
foo();
...

/* fileb.c */
void foo() { }

The question is about proper linkage.

I know that the intent was for any function declared with a prototype
(not including ",...") using only default-widened argument types to link
properly with an old-style function definition with compatible argument
types, as well as with a new-style function definition. An empty list
of arguments (aka "no arguments") vacuously satisfies that condition.


Rajesh S R

unread,
Jul 5, 2007, 6:11:12 AM7/5/07
to
On Jul 5, 12:45 am, Keith Thompson <k...@mib.org> wrote:

> Rajesh S R <SRRajesh1...@gmail.com> writes:> On Jul 4, 9:08 am, Keith Thompson <k...@mib.org> wrote:
> [...]
> >> The real question is, what is the scope if the phrase "or equivalent"?
>
> > I think, "equivalent" is defined in terms of semantics of the main
> > function declaration. "Equivalent" means that you could have any form
> > of declaration which have same semantics as int main(void) or int
> > main(int argc, char *argv[]);
>
> >> Does it apply only to the two-parameter case, or is it intended to
> >> apply to both the zero-parameter and two-parameter cases?
>
> > It should be applicable for both the ways of declaration.
>
> [...]
>
> Ok, suppose you *wanted* the "or equivalent" to appply only to the
> two-parameter case. How would you write that?

I would have written:
or equivalent of latter declaration
if "equivalent" is specifically applicable only with the two
parameter's case.

> It seems to me that you could use the exact words that are currently in the standard.

hmm, I need to agree with you.

Rewriting the words of the standards omitting the paranthetical
remarks and illustrations, I have:

It shall be defined with a return type of int and with no

parameters or with two parameters or equivalent.

The present words of the standards also implies what you stated. The
"conventional interpretation" as I stated in my previous post is
because we know that standards is sensible. But it could also mean
what you say if we make a "crude interpretation" based only on English
language.

One more flaw I find with the present words of the standards is, if
the term "equivalent" extends to return type of main also.

Can we have?

typedef int myInt;

myInt main( void )
{
}

Is this valid?
I think that it is valid, given the fact that standards is sensible
but the words doesn't seem to be implying that.

Jun Woong

unread,
Jul 5, 2007, 7:36:52 AM7/5/07
to
Rajesh S R <SRRajesh1...@gmail.com> wrote:
[...]

>
> One more flaw I find with the present words of the standards is, if
> the term "equivalent" extends to return type of main also.
>
> Can we have?
>
> typedef int myInt;
>
> myInt main( void )
> {
>
> }
>
> Is this valid?
> I think that it is valid, given the fact that standards is sensible
> but the words doesn't seem to be implying that.

DR157 deals with that issue:

http://www.open-std.org/jtc1/sc22/wg14/www/docs/dr_157.html

I think it's fairly sensible to consider the term in question to
cover the typedef cases.


--
Jun, Woong (woong at icu.ac.kr)
Samsung Electronics Co., Ltd.

``All opinions expressed are mine, and do not represent
the official opinions of any organization.''

Keith Thompson

unread,
Jul 5, 2007, 3:28:13 PM7/5/07
to
Jun Woong <wo...@icu.ac.kr> writes:
> Rajesh S R <SRRajesh1...@gmail.com> wrote:
> [...]
>>
>> One more flaw I find with the present words of the standards is, if
>> the term "equivalent" extends to return type of main also.
>>
>> Can we have?
>>
>> typedef int myInt;
>>
>> myInt main( void )
>> {
>>
>> }
>>
>> Is this valid?
>> I think that it is valid, given the fact that standards is sensible
>> but the words doesn't seem to be implying that.
>
> DR157 deals with that issue:
>
> http://www.open-std.org/jtc1/sc22/wg14/www/docs/dr_157.html
>
> I think it's fairly sensible to consider the term in question to
> cover the typedef cases.

I agree that it's sensible -- but DR157 refers to the C90 standard,
which didn't have the "or equivalent" wording. But it does provide
evidence of the intent.

Jun Woong

unread,
Jul 6, 2007, 7:53:27 AM7/6/07
to
Keith Thompson <k...@mib.org> wrote:
> Jun Woong <w...@icu.ac.kr> writes:
[...]

>
> > I think it's fairly sensible to consider the term in question to
> > cover the typedef cases.
>
> I agree that it's sensible -- but DR157 refers to the C90 standard,
> which didn't have the "or equivalent" wording. But it does provide
> evidence of the intent.
>

I suspected that the phrase "or equivalent" was added for making the
intent more clear; in fact I thought, before seeing the DR, the
answer given in it promised to add that phrase.

David R Tribble

unread,
Jul 9, 2007, 11:49:15 AM7/9/07
to
Keith Thompson wrote:
> So, it seems reasonable to assume that
> int main() { /* ... */ }
> is equivalent to
> int main(void) { /* ... */ }
> and is therefore legal. But does the standard actually say so?

Douglas A. Gwyn wrote:
> [...] the general issue is exemplified by


>
> /* filea.c */
> extern void foo(void);
> ...
> foo();
> ...
>
> /* fileb.c */
> void foo() { }
>
> The question is about proper linkage.
>
> I know that the intent was for any function declared with a prototype
> (not including ",...") using only default-widened argument types to link
> properly with an old-style function definition with compatible argument
> types, as well as with a new-style function definition. An empty list
> of arguments (aka "no arguments") vacuously satisfies that condition.

Yes, but given that Keith's code above is defining (and declaring) a
function with no arguments, is it reasonable to assume that the
compiler
can treat main() as having a prototype of main(void) following the
function definition, since it knows everything possible about the
function once it has parsed the closing '}', specifically that it
takes no arguments?

-drt

Douglas A. Gwyn

unread,
Jul 10, 2007, 9:57:23 AM7/10/07
to
David R Tribble wrote:
> Yes, but given that Keith's code above is defining (and declaring) a
> function with no arguments, is it reasonable to assume that the
> compiler
> can treat main() as having a prototype of main(void) following the
> function definition, since it knows everything possible about the
> function once it has parsed the closing '}', specifically that it
> takes no arguments?

Yes; old-style and prototyped declarations/definitions can
match up (link) when the arguments all have default-widened
types. That is vacuously satisfied when they have no arguments.
The "main" function really is not special, with one exception
added in C99: reaching the terminating } automatically returns 0.

Wojtek Lerch

unread,
Jul 10, 2007, 11:11:48 AM7/10/07
to
"Douglas A. Gwyn" <DAG...@null.net> wrote in message news:46939043...@null.net...

> The "main" function really is not special, with one exception
> added in C99: reaching the terminating } automatically returns 0.

It is special in one way: it's called from outside of the program, and instead of describing that call by reference to the semantics of the function call operator, the standard describes it separately. If the standard said that the call is made as if by converting the address of main to either "int(void)" or "int(int,char**)", depending on whether main() was defined with zero or two parameters, and then using the converted pointer as an operand of the function call operator, it would be clear how main() can be defined in programs. But since the standard says no such thing, we have to rely on our guesses on what exactly the standard means when it says "equivalent".

Jun Woong

unread,
Jul 10, 2007, 2:41:01 PM7/10/07
to
"Wojtek Lerch" <Wojte...@yahoo.ca> wrote:
> "Douglas A. Gwyn" <DAG...@null.net> wrote in messagenews:46939043...@null.net...

Agreed.

Or the exemplary forms for defining main() given in the normative
text of the standard could be moved to the Example section with prose
specifying the allowed forms.

I'm on business trip, so hard to dig out the reason "equivalent" was
added there, but strongly suspect it's mainly for handling the
typedef issues rather than for doing the non-prototype definition.


p.s. did you intentionally avoid breaking lines when posting?

Wojtek Lerch

unread,
Jul 10, 2007, 5:20:05 PM7/10/07
to
"Jun Woong" <wo...@icu.ac.kr> wrote in message
news:1184092861.5...@q75g2000hsh.googlegroups.com...

> p.s. did you intentionally avoid breaking lines when posting?

No, I just used the same Outlook Express settings that I have been using for
a few years now. Is it inapproproate to post long unbroken lines to Usenet?
I just noticed that OE disables the "Automatically wrap..." option if the
format is set to MIME/Quoted Printable, and gets enabled when it's set to
anything else. What is the best setting? Maybe I'll try MIME/"Encode text
using None".

Wojtek Lerch

unread,
Jul 10, 2007, 5:22:51 PM7/10/07
to
Yeah, this seems to have worked. Is this a more approproate way of posting?
I have to admit that I like how the unbroken lines fill the width of my
window; but if not all newsreaders handle that nicely, I guess I'll switch
for good...

"Wojtek Lerch" <Wojt...@yahoo.ca> wrote in message
news:5fibg4F...@mid.individual.net...

Keith Thompson

unread,
Jul 10, 2007, 5:40:54 PM7/10/07
to
"Wojtek Lerch" <Wojt...@yahoo.ca> writes:
> Yeah, this seems to have worked. Is this a more approproate way of
> posting? I have to admit that I like how the unbroken lines fill the
> width of my window; but if not all newsreaders handle that nicely, I
> guess I'll switch for good...

Yes, this is much better, thanks.

(My newsreader, for example, wraps long lines, but it does so in the
middle of words. There may be a setting to cause it to wrap at word
boundaries, but I'm too lazy to track it down.)

Douglas A. Gwyn

unread,
Jul 10, 2007, 5:16:45 PM7/10/07
to
Jun Woong wrote:
> I'm on business trip, so hard to dig out the reason "equivalent" was
> added there, but strongly suspect it's mainly for handling the
> typedef issues rather than for doing the non-prototype definition.

It was always intended for the traditional form
int main(argc, argv)
int argc;
char *argv[];
{ ... }
to be supported (by all conforming imlementations).

I agree that the specification is not very clear in this regard.
Frankly, I opposed supporting the main(void) variant and also the
implied return 0; at the closing brace. There was never any
real need for these variations; they were sanctioned for
"political" reasons (such as to bless the sloppy early examples
in K&R).

André Gillibert

unread,
Jul 18, 2007, 10:15:40 AM7/18/07
to
Wojtek Lerch wrote:
> Yeah, this seems to have worked. Is this a more approproate way of
> posting? I have to admit that I like how the unbroken lines fill the
> width of my window; but if not all newsreaders handle that nicely, I
> guess I'll switch for good...

Usenet messages ought to have lines shorter than 80 characters, so that
all news software produce readable text for the end user.
However, you sent a message (whose ID is
<5fhltiF...@mid.individual.net>) whose Content-Type is text/plain and
Content-Transfer-Encoding is quoted-printable.
With the quoted-printable transfer encoding, is primarily use to encode 8
bits characters (ISO-8859-1 in your message) through a 7 bits (ASCII)
network, especially when most of the text consists of ASCII characters.
But, the quoted-printable transfer encoding also limits coded line lengths
to 76 characters. In your post, the longest coded line had 73 characters.

Long lines are encoded as several lines with a soft line break at the end
of every encoded line of a paragraph, except the last one.
The soft line break character is a equal sign (=) immediately preceding
the CR-LF line break sequence.

Wikipedia contains a short description of quoted-printable.
MIME [RFC2045] contains an extensive description.

MIME unaware newsreader will display the encoded text. It will not look
too bad. There will only be those strange equal signs at the end of the
lines.
Newsreader implementing MIME are likely to display long lines correctly...
There may be some newsreader that might not display them well, while they
recognize the quoted-printable transfer encoding and decode it... It's a
transfer encoding, like Base64, not a content-type.
That's why, a "text/plain; format=flowed" Content-Type is a better choice,
in my opinion. You don't really need quoted-printable as your message
contains only US-ASCII characters.

Your message, to which I'm currently answering (ID
<5fibg4F...@mid.individual.net>) looks perfectly fine when read with
a primitive newsreader, including telnet when directly typing the NNTP
protocol.
Actually, unlike the previous message, it uses the text/plain;
format=flowed, which encodes soft breaks as a single ASCII space (0x20)
character preceding a CR-LF sequence.
The longest line of your message contains 77 characters.
Only newsreader aware of this format=flowed parameter, will use it.
The only flaw of your message is that it declares a 7bit
Content-Transfer-Encoding with a 8 bits ISO-8859-1 charset.
This is contrary to the MIME requirement:

> The proper Content-Transfer-Encoding label must always be used.
> Labelling unencoded data containing 8bit characters as "7bit" is not
> allowed, nor is labelling unencoded non-line-oriented data as
> anything other than "binary" allowed.

Thanks goodness, your message happens not to contain any character whose
code point is above 127, so it passed through the network filters.
I think you should configure your Outlook to make it use US-ASCII as
default charset.

Me too, I'm using a newreader supporting format=flowed.
Text/Plain Format Parameter [RFC2646] contains an extensive rationale and
description for it.

If you find this topic interesting, I suggest you read about ProleText
too. There's no IETF RFC for it.

André Gillibert

unread,
Jul 18, 2007, 10:31:35 AM7/18/07
to
On Wed, 18 Jul 2007 16:15:40 +0200, I wrote:
> Usenet messages ought to have lines shorter than 80 characters, so that
> all news software produce readable text for the end user.

My current news application (Opera 9.20) uses both the quoted-printable
content-transfer-encoding and the format=flowed parameter, which produces
ugly messages because "text/plain; format=flowed" makes the software put
soft line breaks to produce lines length as close to 79 characters as
possible. Then, quoted-printable cuts the line to make them fit on 76
columns. This results in half of the lines being very short. I'll have to
configure it better or use another news application.

Excuse me.

0 new messages