main() in C90/C95

I

Ioannis Vranos

Well we all know K&R2 uses main() and not int main(). Also in K&R2, in
chapter 4.1, there is a definition of a function:

dummy() {}

and it is stated that if the returned type is omitted, int is used.


So I suppose in C90/C95

main() is equivalent to int main() right?


That is, the same stuff with C90/95 int variables where,

x= 7;

means int x= 7;
 
H

Harald van Dijk

So I suppose in C90/C95

main() is equivalent to int main() right?
Yes.

That is, the same stuff with C90/95 int variables where,

x= 7;

means int x= 7;

No. x = 7; is an assignment. When x is undeclared, it does not suddenly
become a declaration, it's simply an error.
 
S

santosh

Ioannis said:
Well we all know K&R2 uses main() and not int main(). Also in K&R2, in
chapter 4.1, there is a definition of a function:

dummy() {}

and it is stated that if the returned type is omitted, int is used.


So I suppose in C90/C95

main() is equivalent to int main() right?

Yes. This (implicit int return) was removed from C99.
 
K

Keith Thompson

Harald van Dijk said:
No. x = 7; is an assignment. When x is undeclared, it does not suddenly
become a declaration, it's simply an error.

I think that pre-ANSI C was more forgiving of declarations with
missing types. It was probably the ambiguity of things like "x = 7;",
or even just "x;", that led to the rules being tightened a bit.

Note that (at block scope) this:
auto x = 7;
or this:
auto x;
is a declaration with an implicit type of int. (Of course this is no
longer the case in C99, and is considered poor style even in
C89/C90/C95.)
 
H

Harald van Dijk

I think that pre-ANSI C was more forgiving of declarations with missing
types. It was probably the ambiguity of things like "x = 7;", or even
just "x;", that led to the rules being tightened a bit.

Out of curiosity, do you know of any specific implementations that accept
that?
Note that (at block scope) this:
auto x = 7;
or this:
auto x;
is a declaration with an implicit type of int.

Right. At file scope, it can also be done, for example with
static x = 1;
const y = 2;
(Of course this is no
longer the case in C99, and is considered poor style even in
C89/C90/C95.)

Yes. It's also unfortunate that compilers don't always complain about such
constructs, which would've prevented such constructs accidentally making
their way into code meaning to specify the type explicitly.
 
K

Keith Thompson

Harald van Dijk said:
Out of curiosity, do you know of any specific implementations that accept
that?
[...]

I can think of a couple of old implementations that would probably
accept it without complaint, but I don't currently have easy access to
them.

But gcc 3.4.4 compiles and runs this, and produces the output "x = 42":

=== CUT HERE ===
x;

#include <stdio.h>
int main(void)
{
x = 42;
printf("x = %d\n", x);
return 0;
}
=== AND HERE ===

Of course, it produces a warning on the declaration of x:

c.c:1: warning: data definition has no type or storage class

and it rejects it in pedantic mode. (Note that the warning is
sufficient for compliance.)
 
H

Harald van Dijk

Harald van Dijk said:
Out of curiosity, do you know of any specific implementations that
accept that?
[...]

I can think of a couple of old implementations that would probably
accept it without complaint, but I don't currently have easy access to
them.

But gcc 3.4.4 compiles and runs this, and produces the output "x = 42":

=== CUT HERE ===
x;

#include <stdio.h>
int main(void)
{
x = 42;
printf("x = %d\n", x);
return 0;
}
=== AND HERE ===

Thank you. I now see it also allows 'x = 42;' (and of course, the original
'x= 7;') at global scope, it's just at function scope that it rejects it.
As you mentioned, a diagnostic is generated for the code, so the
standard's requirements are met.
 
I

Ioannis Vranos

I have gcc version 4.1.2 20070626 and the code:

#include <stdio.h>

int main(void)
{
x;

x=7;

printf("%d\n", x);

return 0;
}

[john@localhost src]$ gcc -std=iso9899:1990 main.c -o foobar-cpp
main.c: In function ‘main’:
main.c:5: error: ‘x’ undeclared (first use in this function)
main.c:5: error: (Each undeclared identifier is reported only once
main.c:5: error: for each function it appears in.)
[john@localhost src]$


And in C95 mode:

[john@localhost src]$ gcc -std=iso9899:199409 main.c -o foobar-cpp
main.c: In function ‘main’:
main.c:5: error: ‘x’ undeclared (first use in this function)
main.c:5: error: (Each undeclared identifier is reported only once
main.c:5: error: for each function it appears in.)
[john@localhost src]$



I think it should compile though, and since it doesn't, I consider it a bug.

If it can't work in C90/C95 mode, why do they have these command options
anyway?
 
M

Michael Mair

Harald said:
Out of curiosity, do you know of any specific implementations that accept
that?

Are you asking for current C9x or for pre-ANSI implementations?

I remember books[*] that suggested clever self-compiling source
using (AFAIR)
echo; /*
cc ....
quit
*/
at the beginning of the .c file and reminded the gentle reader
not to waste the int variable echo...


Cheers
Michael

[*]: IIRC, the above is from "C auf dem Amiga" which probably
slumbers along with a couple of RKRMs in my dunge^H basement and
will "definitely go when I move the next time"...
 
K

Keith Thompson

Ioannis Vranos said:
I have gcc version 4.1.2 20070626 and the code:

#include <stdio.h>

int main(void)
{
x;

x=7;

printf("%d\n", x);

return 0;
}

[john@localhost src]$ gcc -std=iso9899:1990 main.c -o foobar-cpp
main.c: In function ‘main’:
main.c:5: error: ‘x’ undeclared (first use in this function)
main.c:5: error: (Each undeclared identifier is reported only once
main.c:5: error: for each function it appears in.)
[john@localhost src]$


And in C95 mode:

[john@localhost src]$ gcc -std=iso9899:199409 main.c -o foobar-cpp [the same]

I think it should compile though, and since it doesn't, I consider it a bug.

The line

"x;"

if x has already been declared is an expression statement that
evaluates and discards the value of x. This would be perfectly valid
if x were declared at file scope.

I don't believe deleting a file-scope declaration of x would transform
the line to a declaration of x with an implicit int type. I don't
remember the C90/C95 rule well enough to be certain that it doesn't,
but I'm fairly sure that the presence or absence of an object
declaration affects the parsing of later code; it can only affect
whether such code is semantically invalid because it does or does not
refer to an undeclared object.
If it can't work in C90/C95 mode, why do they have these command
options anyway?

There are differences between C90, C95, and C99. This just isn't one
of them.

Out of curiosity, why are you asking about this? C90 and C95 allow
implicit int, but that doesn't mean you have to use it. Declaring
"int x;" is unambiguously valid in all versions of C, and is better
than "x;" whether "x;" is legal or not.
 
K

Kenny McCormack

Harald van Dijk said:
Thank you. I now see it also allows 'x = 42;' (and of course, the original
'x= 7;') at global scope, it's just at function scope that it rejects it.
As you mentioned, a diagnostic is generated for the code, so the
standard's requirements are met.

And thank GOD for that.
 
I

Ioannis Vranos

Keith said:
The line

"x;"

if x has already been declared is an expression statement that
evaluates and discards the value of x. This would be perfectly valid
if x were declared at file scope.

I don't believe deleting a file-scope declaration of x would transform
the line to a declaration of x with an implicit int type. I don't
remember the C90/C95 rule well enough to be certain that it doesn't,
but I'm fairly sure that the presence or absence of an object
declaration affects the parsing of later code; it can only affect
whether such code is semantically invalid because it does or does not
refer to an undeclared object.


There are differences between C90, C95, and C99. This just isn't one
of them.

Out of curiosity, why are you asking about this? C90 and C95 allow
implicit int, but that doesn't mean you have to use it. Declaring
"int x;" is unambiguously valid in all versions of C, and is better
than "x;" whether "x;" is legal or not.


The code:

#include <stdio.h>

int main()
{
auto x;

x= 9;

printf("%d\n", x);

printf("%lu %lu\n", sizeof(x), sizeof(int));

return 0;
}


under VC++2008 Express worked as it should in C95 mode. Here is the
output of the compiler:

------ Rebuild All started: Project: demo, Configuration: Debug Win32 ------
Deleting intermediate and output files for project 'demo', configuration
'Debug|Win32'
Compiling...
demo.c
Linking...
LINK : C:\Documents and Settings\Owner\My Documents\Visual Studio
2008\Projects\demo\Debug\demo.exe not found or not built by the last
incremental link; performing full link
Embedding manifest...
Build log was saved at "file://c:\Documents and Settings\Owner\My
Documents\Visual Studio 2008\Projects\demo\demo\Debug\BuildLog.htm"
demo - 0 error(s), 0 warning(s)
========== Rebuild All: 1 succeeded, 0 failed, 0 skipped ==========


It outputs:

9
4 4
Press any key to continue . . .



Under gcc version 4.1.2


C90 mode:

[john@localhost src]$ gcc -std=iso9899:1990 -pedantic-errors -Wall
main.c -o foobar-cpp
main.c: In function ‘main’:
main.c:5: warning: type defaults to ‘int’ in declaration of ‘x’
main.c:11: warning: format ‘%lu’ expects type ‘long unsigned int’, but
argument 2 has type ‘unsigned int’
main.c:11: warning: format ‘%lu’ expects type ‘long unsigned int’, but
argument 3 has type ‘unsigned int’
[john@localhost src]$


[john@localhost src]$ ./foobar-cpp
9
4 4
[john@localhost src]$


[john@localhost src]$ gcc -std=iso9899:1990 main.c -o foobar-cpp
[john@localhost src]$ ./foobar-cpp
9
4 4
[john@localhost src]$



C95 mode:

[john@localhost src]$ gcc -std=iso9899:199409 main.c -o foobar-cpp
[john@localhost src]$ ./foobar-cpp
9
4 4
[john@localhost src]$


[john@localhost src]$ gcc -std=iso9899:199409 -pedantic-errors -Wall
main.c -o foobar-cpp
main.c: In function ‘main’:
main.c:5: warning: type defaults to ‘int’ in declaration of ‘x’
main.c:11: warning: format ‘%lu’ expects type ‘long unsigned int’, but
argument 2 has type ‘unsigned int’
main.c:11: warning: format ‘%lu’ expects type ‘long unsigned int’, but
argument 3 has type ‘unsigned int’
[john@localhost src]$ ./foobar-cpp
9
4 4
[john@localhost src]$


Without the -Wall we get no warnings:

[john@localhost src]$ gcc -std=iso9899:199409 -pedantic-errors main.c -o
foobar-cpp
[john@localhost src]$ ./foobar-cpp
9
4 4
[john@localhost src]$



For the code:

#include <stdio.h>

int main()
{
x;

x= 9;

printf("%d\n", x);

printf("%lu %lu\n", sizeof(x), sizeof(int));

return 0;
}


under VC++2008 Express (that supports C95):

------ Rebuild All started: Project: demo, Configuration: Debug Win32 ------
Deleting intermediate and output files for project 'demo', configuration
'Debug|Win32'
Compiling...
demo.c
c:\documents and settings\owner\my documents\visual studio
2008\projects\demo\demo\demo.c(5) : error C2065: 'x' : undeclared identifier
c:\documents and settings\owner\my documents\visual studio
2008\projects\demo\demo\demo.c(7) : error C2065: 'x' : undeclared identifier
c:\documents and settings\owner\my documents\visual studio
2008\projects\demo\demo\demo.c(9) : error C2065: 'x' : undeclared identifier
c:\documents and settings\owner\my documents\visual studio
2008\projects\demo\demo\demo.c(11) : error C2065: 'x' : undeclared
identifier
Build log was saved at "file://c:\Documents and Settings\Owner\My
Documents\Visual Studio 2008\Projects\demo\demo\Debug\BuildLog.htm"
demo - 4 error(s), 0 warning(s)
========== Rebuild All: 0 succeeded, 1 failed, 0 skipped ==========



Both compilers also compile the following code successfully:


#include <stdio.h>

test(void)
{
}


int main()
{
auto x;

x= 9;

printf("%d\n", x);

printf("%lu %lu\n", sizeof(x), sizeof(int));

return 0;
}




So since the above codes work the same with both VC++ 2008 Express
Edition and gcc, while the statement does not work in a similar way with
both compilers, I wonder whether the C90/C95 standards, required at
least one keyword for the implicit int declaration, like auto.
 
I

Ioannis Vranos

A minor correction:


Ioannis said:
Keith said:
The line

"x;"

if x has already been declared is an expression statement that
evaluates and discards the value of x. This would be perfectly valid
if x were declared at file scope.

I don't believe deleting a file-scope declaration of x would transform
the line to a declaration of x with an implicit int type. I don't
remember the C90/C95 rule well enough to be certain that it doesn't,
but I'm fairly sure that the presence or absence of an object
declaration affects the parsing of later code; it can only affect
whether such code is semantically invalid because it does or does not
refer to an undeclared object.


There are differences between C90, C95, and C99. This just isn't one
of them.

Out of curiosity, why are you asking about this? C90 and C95 allow
implicit int, but that doesn't mean you have to use it. Declaring
"int x;" is unambiguously valid in all versions of C, and is better
than "x;" whether "x;" is legal or not.


The code:

#include <stdio.h>

int main()
{
auto x;

x= 9;

printf("%d\n", x);

printf("%lu %lu\n", sizeof(x), sizeof(int));

return 0;
}


under VC++2008 Express worked as it should in C95 mode. Here is the
output of the compiler:

------ Rebuild All started: Project: demo, Configuration: Debug Win32
------
Deleting intermediate and output files for project 'demo', configuration
'Debug|Win32'
Compiling...
demo.c
Linking...
LINK : C:\Documents and Settings\Owner\My Documents\Visual Studio
2008\Projects\demo\Debug\demo.exe not found or not built by the last
incremental link; performing full link
Embedding manifest...
Build log was saved at "file://c:\Documents and Settings\Owner\My
Documents\Visual Studio 2008\Projects\demo\demo\Debug\BuildLog.htm"
demo - 0 error(s), 0 warning(s)
========== Rebuild All: 1 succeeded, 0 failed, 0 skipped ==========


It outputs:

9
4 4
Press any key to continue . . .



Under gcc version 4.1.2


C90 mode:

[john@localhost src]$ gcc -std=iso9899:1990 -pedantic-errors -Wall
main.c -o foobar-cpp
main.c: In function ‘main’:
main.c:5: warning: type defaults to ‘int’ in declaration of ‘x’
main.c:11: warning: format ‘%lu’ expects type ‘long unsigned int’, but
argument 2 has type ‘unsigned int’
main.c:11: warning: format ‘%lu’ expects type ‘long unsigned int’, but
argument 3 has type ‘unsigned int’
[john@localhost src]$


[john@localhost src]$ ./foobar-cpp
9
4 4
[john@localhost src]$


[john@localhost src]$ gcc -std=iso9899:1990 main.c -o foobar-cpp
[john@localhost src]$ ./foobar-cpp
9
4 4
[john@localhost src]$



C95 mode:

[john@localhost src]$ gcc -std=iso9899:199409 main.c -o foobar-cpp
[john@localhost src]$ ./foobar-cpp
9
4 4
[john@localhost src]$


[john@localhost src]$ gcc -std=iso9899:199409 -pedantic-errors -Wall
main.c -o foobar-cpp
main.c: In function ‘main’:
main.c:5: warning: type defaults to ‘int’ in declaration of ‘x’
main.c:11: warning: format ‘%lu’ expects type ‘long unsigned int’, but
argument 2 has type ‘unsigned int’
main.c:11: warning: format ‘%lu’ expects type ‘long unsigned int’, but
argument 3 has type ‘unsigned int’
[john@localhost src]$ ./foobar-cpp
9
4 4
[john@localhost src]$


Without the -Wall we get no warnings:

[john@localhost src]$ gcc -std=iso9899:199409 -pedantic-errors main.c -o
foobar-cpp
[john@localhost src]$ ./foobar-cpp
9
4 4
[john@localhost src]$



For the code:

#include <stdio.h>

int main()
{
x;

x= 9;

printf("%d\n", x);

printf("%lu %lu\n", sizeof(x), sizeof(int));

return 0;
}


under VC++2008 Express (that supports C95):

------ Rebuild All started: Project: demo, Configuration: Debug Win32
------
Deleting intermediate and output files for project 'demo', configuration
'Debug|Win32'
Compiling...
demo.c
c:\documents and settings\owner\my documents\visual studio
2008\projects\demo\demo\demo.c(5) : error C2065: 'x' : undeclared
identifier
c:\documents and settings\owner\my documents\visual studio
2008\projects\demo\demo\demo.c(7) : error C2065: 'x' : undeclared
identifier
c:\documents and settings\owner\my documents\visual studio
2008\projects\demo\demo\demo.c(9) : error C2065: 'x' : undeclared
identifier
c:\documents and settings\owner\my documents\visual studio
2008\projects\demo\demo\demo.c(11) : error C2065: 'x' : undeclared
identifier
Build log was saved at "file://c:\Documents and Settings\Owner\My
Documents\Visual Studio 2008\Projects\demo\demo\Debug\BuildLog.htm"
demo - 4 error(s), 0 warning(s)
========== Rebuild All: 0 succeeded, 1 failed, 0 skipped ==========



Both compilers also compile the following code successfully:


#include <stdio.h>

test(void)
{ return 0;
}


int main()
{
auto x;

x= 9;

printf("%d\n", x);

printf("%lu %lu\n", sizeof(x), sizeof(int));

return 0;
}




So since the above codes work the same with both VC++ 2008 Express
Edition and gcc, while the statement does not work in a similar way with
both compilers, I wonder whether the C90/C95 standards, required at
least one keyword for the implicit int declaration, like auto.
 
I

Ioannis Vranos

The text corrected:


Keith said:
>
> The line
>
> "x;"
>
> if x has already been declared is an expression statement that
> evaluates and discards the value of x. This would be perfectly valid
> if x were declared at file scope.
>
> I don't believe deleting a file-scope declaration of x would transform
> the line to a declaration of x with an implicit int type. I don't
> remember the C90/C95 rule well enough to be certain that it doesn't,
> but I'm fairly sure that the presence or absence of an object
> declaration affects the parsing of later code; it can only affect
> whether such code is semantically invalid because it does or does not
> refer to an undeclared object.
>
>
> There are differences between C90, C95, and C99. This just isn't one
> of them.
>
> Out of curiosity, why are you asking about this? C90 and C95 allow
> implicit int, but that doesn't mean you have to use it. Declaring
> "int x;" is unambiguously valid in all versions of C, and is better
> than "x;" whether "x;" is legal or not.


The code:

#include <stdio.h>

int main()
{
auto x;

x= 9;

printf("%d\n", x);

printf("%lu %lu\n", sizeof(x), sizeof(int));

return 0;
}


under VC++2008 Express worked as it should in C95 mode. Here is the
output of the compiler:

------ Rebuild All started: Project: demo, Configuration: Debug Win32 ------
Deleting intermediate and output files for project 'demo', configuration
'Debug|Win32'
Compiling...
demo.c
Linking...
LINK : C:\Documents and Settings\Owner\My Documents\Visual Studio
2008\Projects\demo\Debug\demo.exe not found or not built by the last
incremental link; performing full link
Embedding manifest...
Build log was saved at "file://c:\Documents and Settings\Owner\My
Documents\Visual Studio 2008\Projects\demo\demo\Debug\BuildLog.htm"
demo - 0 error(s), 0 warning(s)
========== Rebuild All: 1 succeeded, 0 failed, 0 skipped ==========


It outputs:

9
4 4
Press any key to continue . . .



Under gcc version 4.1.2


C90 mode:

[john@localhost src]$ gcc -std=iso9899:1990 -pedantic-errors -Wall
main.c -o foobar-cpp
main.c: In function ‘main’:
main.c:5: warning: type defaults to ‘int’ in declaration of ‘x’
main.c:11: warning: format ‘%lu’ expects type ‘long unsigned int’, but
argument 2 has type ‘unsigned int’
main.c:11: warning: format ‘%lu’ expects type ‘long unsigned int’, but
argument 3 has type ‘unsigned int’
[john@localhost src]$


[john@localhost src]$ ./foobar-cpp
9
4 4
[john@localhost src]$


[john@localhost src]$ gcc -std=iso9899:1990 main.c -o foobar-cpp
[john@localhost src]$ ./foobar-cpp
9
4 4
[john@localhost src]$



C95 mode:

[john@localhost src]$ gcc -std=iso9899:199409 main.c -o foobar-cpp
[john@localhost src]$ ./foobar-cpp
9
4 4
[john@localhost src]$


[john@localhost src]$ gcc -std=iso9899:199409 -pedantic-errors -Wall
main.c -o foobar-cpp
main.c: In function ‘main’:
main.c:5: warning: type defaults to ‘int’ in declaration of ‘x’
main.c:11: warning: format ‘%lu’ expects type ‘long unsigned int’, but
argument 2 has type ‘unsigned int’
main.c:11: warning: format ‘%lu’ expects type ‘long unsigned int’, but
argument 3 has type ‘unsigned int’
[john@localhost src]$ ./foobar-cpp
9
4 4
[john@localhost src]$


Without the -Wall we get no warnings:

[john@localhost src]$ gcc -std=iso9899:199409 -pedantic-errors main.c -o
foobar-cpp
[john@localhost src]$ ./foobar-cpp
9
4 4
[john@localhost src]$



For the code:

#include <stdio.h>

int main()
{
x;

x= 9;

printf("%d\n", x);

printf("%lu %lu\n", sizeof(x), sizeof(int));

return 0;
}


under VC++2008 Express (that supports C95):

------ Rebuild All started: Project: demo, Configuration: Debug Win32 ------
Deleting intermediate and output files for project 'demo', configuration
'Debug|Win32'
Compiling...
demo.c
c:\documents and settings\owner\my documents\visual studio
2008\projects\demo\demo\demo.c(5) : error C2065: 'x' : undeclared identifier
c:\documents and settings\owner\my documents\visual studio
2008\projects\demo\demo\demo.c(7) : error C2065: 'x' : undeclared identifier
c:\documents and settings\owner\my documents\visual studio
2008\projects\demo\demo\demo.c(9) : error C2065: 'x' : undeclared identifier
c:\documents and settings\owner\my documents\visual studio
2008\projects\demo\demo\demo.c(11) : error C2065: 'x' : undeclared
identifier
Build log was saved at "file://c:\Documents and Settings\Owner\My
Documents\Visual Studio 2008\Projects\demo\demo\Debug\BuildLog.htm"
demo - 4 error(s), 0 warning(s)
========== Rebuild All: 0 succeeded, 1 failed, 0 skipped ==========



Both compilers also compile the following code successfully:


#include <stdio.h>

test(void)
{
return 0;
}


int main()
{
auto x;

x= 9;

printf("%d\n", x);

printf("%lu %lu\n", sizeof(x), sizeof(int));

return 0;
}




So since the above codes that get compiled successfully, work the same
with both VC++ 2008 Express Edition and gcc, while the x; statement does
not work, again in a similar way with both compilers, I wonder whether
the C90/C95 standards, required at least one keyword for the implicit
int declaration of a variable, like auto.
 

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

Similar Threads


Members online

Forum statistics

Threads
473,755
Messages
2,569,537
Members
45,023
Latest member
websitedesig25

Latest Threads

Top