Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Is this legal C?

Reply
Thread Tools

Is this legal C?

 
 
Max
Guest
Posts: n/a
 
      06-27-2008
This was asked in a C test. Is the following code legal C?
Is it legal in C90? C99?

#define main()
int main
#define mainbody () { return 0; }
mainbody

 
Reply With Quote
 
 
 
 
Keith Thompson
Guest
Posts: n/a
 
      06-28-2008
pete <(E-Mail Removed)> writes:
> Max wrote:
> > This was asked in a C test. Is the following code legal C?
> > Is it legal in C90? C99?

>
> Yes. Yes.
>
> > #define main()
> > int main
> > #define mainbody () { return 0; }
> > mainbody

>
> It's as legal as
>
> int main(){return 0;}
>
> is.


There's a fairly subtle argument that "int main()" is not actually
required to be supported, but for all practical purposes it's ok.
"int main(void)" is better, though.

Note that "main" is defined as a function-like macro, and "mainbody"
is defined as an object-like macro.

Compiling the code and/or examining the preprocessor output (assuming
your compiler supports this) won't definitively answer the question,
but it will give some good hints.

--
Keith Thompson (The_Other_Keith) http://www.velocityreviews.com/forums/(E-Mail Removed) <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
 
Reply With Quote
 
 
 
 
Kenny McCormack
Guest
Posts: n/a
 
      06-28-2008
In article <(E-Mail Removed)>,
Richard Heathfield <(E-Mail Removed)> wrote:
>Keith Thompson said:
>
><snip>
>
>> There's a fairly subtle argument that "int main()" is not actually
>> required to be supported,

>
>I remember that this has come up before. I wasn't completely convinced
>then, and I'm not completely convinced now.
>
>A function definition that has no parameter list takes no parameters, and
>is thus precisely equivalent to int main(void) in semantic terms. (Note
>that we're not talking about mere definitions here.)
>
>Since the Standard only requires of main that it be equivalent to int
>main(void) or int main(int argc, char **argv), and since int main() is
>equivalent to int main(void), it seems to me that int main() is perfectly
>acceptable - to the compiler, at least, even though the stylist might
>object.


Nice to see clc regulars returning to their home territory.

Coming soon: Casting the return value of malloc().

 
Reply With Quote
 
Max
Guest
Posts: n/a
 
      06-28-2008
pete wrote:

>Max wrote:
>> This was asked in a C test. Is the following code legal C?
>> Is it legal in C90? C99?

>
>Yes. Yes.


Thanks.

>> #define main()
>> int main
>> #define mainbody () { return 0; }
>> mainbody

>
>It's as legal as
>
> int main(){return 0;}
>
>is.


 
Reply With Quote
 
Keith Thompson
Guest
Posts: n/a
 
      06-28-2008
Richard Heathfield <(E-Mail Removed)> writes:
> Keith Thompson said:
> <snip>
>
> > There's a fairly subtle argument that "int main()" is not actually
> > required to be supported,

>
> I remember that this has come up before. I wasn't completely convinced
> then, and I'm not completely convinced now.
>
> A function definition that has no parameter list takes no parameters, and
> is thus precisely equivalent to int main(void) in semantic terms. (Note
> that we're not talking about mere definitions here.)
>
> Since the Standard only requires of main that it be equivalent to int
> main(void) or int main(int argc, char **argv), and since int main() is
> equivalent to int main(void), it seems to me that int main() is perfectly
> acceptable - to the compiler, at least, even though the stylist might
> object.
>
> <snip>


Reference: C99 5.1.2.2.1 Program startup

For this definition:

int main() { return 0; }

to be valid (by "valid" here, I mean that an implementation is
required to support it with well-defined behavior), it must be
"equivalent" to this definition, which is undeniably valid:

int main(void) { return 0; }

It's equivalent by itself, when considered only as a self-contained
function definition. However, the definition also provides a
*declaration*. I assert that the two definitions are *not*
equivalent, because they provide non-equivalent declarations.

Assume an implementation that does accept "int main() { return 0; }"
with the obvious meaning (this is allowed by the "or in some other
implementation-defined manner" clause if not by the "or equivalent"
clause). Or, if you prefer, assume that "int main() { return 0; }" is
valid. Then this program:

int main() { return 0; }

void foo(void) { main(42); }

is valid (the declaration of main requires an unspecified number and
type of arguments; the call to main would invoke undefined behavior if
it were executed, but it never is). But this program:

int main(void) { return 0; }

void foo(void) { main(42); }

violates the constraint in C99 6.5.2.2p2.

Therefore, a definition using "int main()" is not equivalent to one
using "int main(void)", and thus an implementation needn't support it.

Note that, assuming my reasoning is correct, "int main()" doesn't
violate any constraint. A program that uses it merely invokes
undefined behavior. As it happens, every implementation I know of
responds to this undefined behavior by quietly accepting the
definition.

I'm not convinced that this was the intent, and I'd be unsurprised to
find that the members of the committee either intended "int main()" to
be valid, or just didn't think about it.

Implementers can avoid the issue by accepting "int main()", and
programmers can avoid the issue by using not using "int main()", so
it's not a huge deal either way.

I see I posted a similar question to comp.std.c last July,
subject "Is 'int main() { /* ... */ }' valid?":

http://groups.google.com/group/comp....630179750145a9

but re-reading that thread I see I was actually asking about a
different subtle issue.

--
Keith Thompson (The_Other_Keith) (E-Mail Removed) <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
 
Reply With Quote
 
Keith Thompson
Guest
Posts: n/a
 
      06-28-2008
pete <(E-Mail Removed)> writes:
> Keith Thompson wrote:
> > pete <(E-Mail Removed)> writes:
> >> Max wrote:
> >>> This was asked in a C test. Is the following code legal C?
> >>> Is it legal in C90? C99?
> >> Yes. Yes.
> >>
> >>> #define main()
> >>> int main
> >>> #define mainbody () { return 0; }
> >>> mainbody
> >> It's as legal as
> >>
> >> int main(){return 0;}
> >>
> >> is.

> > There's a fairly subtle argument that "int main()" is not actually
> > required to be supported, but for all practical purposes it's ok.
> > "int main(void)" is better, though.
> > Note that "main" is defined as a function-like macro, and "mainbody"
> > is defined as an object-like macro.

>
> main isn't defined as a macro.
> main() is defined as a macro.


I understand what you mean, but a macro name is an identifier; the
parentheses aren't part of the name.

See also the standard's definitions of "object-like macro" and
"function-like macro".

#include <stdio.h>

void Keith_Is_Right(void);

#define main()
int main
#define mainbody () { Keith_Is_Right(); return 0; }
mainbody

void Keith_Is_Right(void)
{
#ifdef main
puts("Yes, main is defined as a macro.");
#else
puts("Never mind.");
#endif
}

--
Keith Thompson (The_Other_Keith) (E-Mail Removed) <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
 
Reply With Quote
 
Keith Thompson
Guest
Posts: n/a
 
      06-28-2008
Richard Heathfield <(E-Mail Removed)> writes:
> Keith Thompson said:

[...]
> > Reference: C99 5.1.2.2.1 Program startup
> >
> > For this definition:
> >
> > int main() { return 0; }
> >
> > to be valid (by "valid" here, I mean that an implementation is
> > required to support it with well-defined behavior), it must be
> > "equivalent" to this definition, which is undeniably valid:
> >
> > int main(void) { return 0; }
> >
> > It's equivalent by itself, when considered only as a self-contained
> > function definition. However, the definition also provides a
> > *declaration*. I assert that the two definitions are *not*
> > equivalent, because they provide non-equivalent declarations.

>
> I disagree, because of 3.5.4.3 (C89):
>
> "An identifier list declares only the identifiers of the parameters of the
> function. An empty list in a function declarator that is part of a
> function definition specifies that the function has no parameters. The
> empty list in a function declarator that is not part of a function
> definition specifies that no information about the number or types of the
> parameters is supplied."
>
> The wording is almost identical in C99:
>
> 6.7.5.3(14) (C99):
> "An identifier list declares only the identifiers of the parameters of the
> function. An empty list in a function declarator that is part of a
> definition of that function specifies that the function has no parameters.
> The empty list in a function declarator that is not part of a definition
> of that function specifies that no information about the number or types
> of the parameters is supplied."
>
> So the empty list in int main() { return 0; } specifies that the function
> has no parameters, which means that it is semantically equivalent to int
> main(void), QED.


Yes, the empty list specifies, for purposes of the definition (the
body of the function), that the function has no parameters. So the
two definitions are equivalent in what they say about main's
parameters.

But they are not equivalent in other ways.

An empty list doesn't specify that a caller must pass no arguments,
because it doesn't provide a prototype.

Given "int main(void) { ... }", an attempt to call "main(42)" violates
a constraint. Given "int main(void) { ... }", such a call does not
violate a constraint (though it does invoke undefined behavior).

A prototype is not equivalent to the absence of a prototype.

--
Keith Thompson (The_Other_Keith) (E-Mail Removed) <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
 
Reply With Quote
 
Willem
Guest
Posts: n/a
 
      06-28-2008
Max wrote:
) This was asked in a C test. Is the following code legal C?
) Is it legal in C90? C99?
)
) #define main()
) int main
) #define mainbody () { return 0; }
) mainbody

Correct me if I'm wrong, but after preprocessing, doesn't this expand to:

---
int main

{ return 0; }
---

Which is missing the parens after main, and so is illegal ?


SaSW, Willem
--
Disclaimer: I am in no way responsible for any of the statements
made in the above text. For all I know I might be
drugged or something..
No I'm not paranoid. You all think I'm paranoid, don't you !
#EOT
 
Reply With Quote
 
Erik Trulsson
Guest
Posts: n/a
 
      06-28-2008
Willem <(E-Mail Removed)> wrote:
> Max wrote:
> ) This was asked in a C test. Is the following code legal C?
> ) Is it legal in C90? C99?
> )
> ) #define main()
> ) int main
> ) #define mainbody () { return 0; }
> ) mainbody
>
> Correct me if I'm wrong, but after preprocessing, doesn't this expand to:
>
> ---
> int main
>
> { return 0; }
> ---
>
> Which is missing the parens after main, and so is illegal ?


You are wrong. 'main' is defined as a function-like macro taking no arguments
and expanding to an empty string. The 'main' in "int main" does not match an
invocation of this macro and is thus not replaced.
'mainbody' on the other hand is an object-like macro which is defined as "()
{ return 0; }".

(It makes a great deal of difference if there is a space or not between the
macro name and a '(' when defining a macro.)

After preprocessing it should thus expand to:

---

int main

() { return 0; }
---

Which is of course equivalent to
---
int main() { return 0; }
---
which is quite legal.


--
<Insert your favourite quote here.>
Erik Trulsson
(E-Mail Removed)
 
Reply With Quote
 
Hans Schneider
Guest
Posts: n/a
 
      06-28-2008
pete schrieb:

> Max wrote:
>> This was asked in a C test. Is the following code legal C?
>> Is it legal in C90? C99?

>
> Yes. Yes.
>
>> #define main()
>> int main
>> #define mainbody () { return 0; }
>> mainbody


Must be some gcc extension. This compiles not even with LCC-WIN32:

lc -ansic -O -c main.c
Error main.c: 4 Syntax error; missing semicolon before `mainbody'
Warning main.c: 4 no type specified. Defaulting to int
Error main.c: 5 Syntax error; missing semicolon before `end of input'
2 errors, 1 warning
1 error

>
> It's as legal as
>
> int main(){return 0;}
>
> is.


 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Is it legal to write an logical equation for a FPGA LUT in claims of a patent? Weng Tianxiang VHDL 12 12-10-2005 03:49 PM
Research: File-sharers big legal download spenders. Silverstrand Front Page News 0 07-27-2005 03:00 PM
State machine transition on internal signals - is it legal? Divyang M VHDL 9 05-18-2005 03:58 PM
State machine transition on internal signals -- is it legal? Divyang M VHDL 1 05-15-2005 09:36 AM
Is this legal? Valentin Tihomirov VHDL 20 10-29-2003 10:31 AM



Advertisments