By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
440,905 Members | 879 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 440,905 IT Pros & Developers. It's quick & easy.

what does this warning mean ?

P: n/a
what does this warning mean ?
#include <stdio.h>

int main()
{
long l = 100;

printf("l is %li\n", l * 10L);

return 0;
}
when i compile this program with lcc-win32 it prints

lcc -A -ansic -O long.c -o long.obj
Warning c:\tmp\long.c: 4 old-style function definition for 'main'
Warning c:\tmp\long.c: 4 missing prototype for 'main'
Warning c:\tmp\long.c: 4 'int main()' is a non-ANSI definition
Warning c:\tmp\long.c: 7 printf argument mismatch for format i.
Expected long int got int
0 errors, 4 warnings
warning 1-3: how to give prototype for main ?

warning 4: i gave it long int but it says it got int . even
'(long)l * 10L' gives same warning . how to cast this properly ?
is it safe to ignore ???

gcc prints no warnings .

--
mfg, heinrich :)

Sep 27 '07 #1
Share this Question
Share on Google+
92 Replies


P: n/a
Heinrich Pumpernickel said:
what does this warning mean ?
#include <stdio.h>

int main()
{
long l = 100;

printf("l is %li\n", l * 10L);

return 0;
}
when i compile this program with lcc-win32 it prints

lcc -A -ansic -O long.c -o long.obj
Warning c:\tmp\long.c: 4 old-style function definition for 'main'
Warning c:\tmp\long.c: 4 missing prototype for 'main'
Warning c:\tmp\long.c: 4 'int main()' is a non-ANSI definition
Warning c:\tmp\long.c: 7 printf argument mismatch for format i.
Expected long int got int
0 errors, 4 warnings
warning 1-3: how to give prototype for main ?
change int main() to int main(void)
>
warning 4: i gave it long int but it says it got int . even
'(long)l * 10L' gives same warning .
Implementations are given licence to produce diagnostic messages for any
reason they like. Mostly, implementors are very good at not giving out
spurious messages, but sometimes the occasional duff message is displayed.
This is one such case.

The "usual arithmetic conversions" require that "if either operand has type
long int, the other operand is converted to long int", which is doubly
true here, so we definitely have long * long, which definitely results in
a long because "The purpose is to yield a common type, which is also the
type of the result" (both citations are from 3.2.1.5 of C89).

So the code is right. The implementation's production of a diagnostic
message is not non-conforming (because implementations are allowed to
produce any old rubbish in the diagnostics as long as correct code works
correctly - and I presume it does?), but it does demonstrate low QoI, and
it makes you wonder how many other spurious diagnostics your
implementation is producing.
how to cast this properly ?
Please don't. There's no point. The value already has the proper type.
Casting is not going to help.
is it safe to ignore ???
The code is legal C. Is it safe to use an implementation that gives
misleading diagnostics for legal C? That's a judgement call that nobody
else (apart from perhaps your boss) can make for you.
gcc prints no warnings .
Ah, there's a Great Big Hint for you if ever I saw one.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Sep 27 '07 #2

P: n/a
Heinrich Pumpernickel <la****@linuxmail.orgwrites:
what does this warning mean ?
#include <stdio.h>

int main()
{
long l = 100;

printf("l is %li\n", l * 10L);

return 0;
}
when i compile this program with lcc-win32 it prints

lcc -A -ansic -O long.c -o long.obj
Warning c:\tmp\long.c: 4 old-style function definition for 'main'
Warning c:\tmp\long.c: 4 missing prototype for 'main'
Warning c:\tmp\long.c: 4 'int main()' is a non-ANSI definition
Warning c:\tmp\long.c: 7 printf argument mismatch for format i.
Expected long int got int
0 errors, 4 warnings
warning 1-3: how to give prototype for main ?
Use 'int main(void)' rather than 'int main()'.
warning 4: i gave it long int but it says it got int . even
'(long)l * 10L' gives same warning . how to cast this properly ?
is it safe to ignore ???

gcc prints no warnings .
I don't know. Did you copy-and-paste the exact code and error
messages? If not, check for transcription errors, such as digit 1'
vs. letter 'l'.

It could be a bug in lcc-win32. Post the details to
comp.compilers.lcc, or use whatever support channels are available.

--
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"
Sep 27 '07 #3

P: n/a
Keith Thompson said:
Heinrich Pumpernickel <la****@linuxmail.orgwrites:
<snip>
>warning 4: i gave it long int but it says it got int . even
'(long)l * 10L' gives same warning . how to cast this properly ?
is it safe to ignore ???
<snip>
It could be a bug in lcc-win32.
Nothing he has said suggests anything of the sort. It is strictly a QoI
matter. A bug-free conforming implementation could legally produce that
diagnostic message, despite correct code and correct runtime behaviour.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Sep 27 '07 #4

P: n/a
Heinrich Pumpernickel wrote:
what does this warning mean ?
#include <stdio.h>

int main()
{
long l = 100;

printf("l is %li\n", l * 10L);

return 0;
}
when i compile this program with lcc-win32 it prints

lcc -A -ansic -O long.c -o long.obj
Warning c:\tmp\long.c: 4 old-style function definition for 'main'
Warning c:\tmp\long.c: 4 missing prototype for 'main'
Warning c:\tmp\long.c: 4 'int main()' is a non-ANSI definition
Warning c:\tmp\long.c: 7 printf argument mismatch for format i.
Expected long int got int
0 errors, 4 warnings
Keep in mind that a compiler is free to issue as many
diagnostic messages as it likes, about any matters it wants
to, even in situations where the Standard does not require
a diagnostic. If it wants to complain about the way you
indent your code or about your choice of variable names or
about being forced to compile code after quitting time on
Friday, it can do so. It can't reject the program for such
a reason, but it can issue diagnostics anyhow.

Because of this, the goal of "Code so clean it gets no
warnings from any compiler" is not always achievable.
warning 1-3: how to give prototype for main ?
Modern style recommends `int main(void)', but there is
nothing actually wrong with the code as written. In particular,
your definition of main() conforms to the original 1989 ANSI
C Standard and all its successors, despite what the "non-ANSI"
warning says.
warning 4: i gave it long int but it says it got int . even
'(long)l * 10L' gives same warning . how to cast this properly ?
is it safe to ignore ???
The code is correct. I don't know why the compiler says
it isn't.
gcc prints no warnings .
Plain "gcc" lets quite a lot of looseness get by. But
even if you crank it up to "gcc -Wall -W -ansi -pedantic"
I don't think it will issue warnings for your code.

Some compilers can translate several different (but usually
related) languages if invoked or configured for them. Are you
sure your compiler is configured to recognize C, and not some
related language like C++ or Objective-C?

--
Eric Sosman
es*****@ieee-dot-org.invalid
Sep 27 '07 #5

P: n/a
On Thu, 27 Sep 2007 02:47:17 +0000, Richard Heathfield
<rj*@see.sig.invalidwrote:
>Heinrich Pumpernickel said:
>what does this warning mean ?
#include <stdio.h>

int main()
{
long l = 100;

printf("l is %li\n", l * 10L);

return 0;
}
when i compile this program with lcc-win32 it prints

lcc -A -ansic -O long.c -o long.obj
Warning c:\tmp\long.c: 4 old-style function definition for 'main'
Warning c:\tmp\long.c: 4 missing prototype for 'main'
Warning c:\tmp\long.c: 4 'int main()' is a non-ANSI definition
Warning c:\tmp\long.c: 7 printf argument mismatch for format i.
Expected long int got int
0 errors, 4 warnings
warning 1-3: how to give prototype for main ?

change int main() to int main(void)
>>
warning 4: i gave it long int but it says it got int . even
'(long)l * 10L' gives same warning .

Implementations are given licence to produce diagnostic messages for any
reason they like. Mostly, implementors are very good at not giving out
spurious messages, but sometimes the occasional duff message is displayed.
This is one such case.

The "usual arithmetic conversions" require that "if either operand has type
long int, the other operand is converted to long int", which is doubly
true here, so we definitely have long * long, which definitely results in
a long because "The purpose is to yield a common type, which is also the
type of the result" (both citations are from 3.2.1.5 of C89).

So the code is right. The implementation's production of a diagnostic
message is not non-conforming (because implementations are allowed to
produce any old rubbish in the diagnostics as long as correct code works
correctly - and I presume it does?), but it does demonstrate low QoI, and
it makes you wonder how many other spurious diagnostics your
implementation is producing.
>how to cast this properly ?

Please don't. There's no point. The value already has the proper type.
Casting is not going to help.
somebody suggested

printf("l is %li\n", (long)(l * 10L));

and now this warning disappeared . can l * 10L ever be int ?
(my boss says thats illegal)
>is it safe to ignore ???

The code is legal C. Is it safe to use an implementation that gives
misleading diagnostics for legal C? That's a judgement call that nobody
else (apart from perhaps your boss) can make for you.
>gcc prints no warnings .

Ah, there's a Great Big Hint for you if ever I saw one.
--
mfg, heinrich :)

Sep 27 '07 #6

P: n/a
Heinrich Pumpernickel wrote:
>
On Thu, 27 Sep 2007 02:47:17 +0000, Richard Heathfield
<rj*@see.sig.invalidwrote:
Heinrich Pumpernickel said:
what does this warning mean ?
#include <stdio.h>

int main()
{
long l = 100;

printf("l is %li\n", l * 10L);

return 0;
}
somebody suggested

printf("l is %li\n", (long)(l * 10L));

and now this warning disappeared . can l * 10L ever be int ?
No.
Even just (l * 10) is still type long int.

--
pete
Sep 27 '07 #7

P: n/a
Heinrich Pumpernickel said:

<snip>
>
somebody suggested

printf("l is %li\n", (long)(l * 10L));

and now this warning disappeared .
The cast is unnecessary and bad style. When you multiply a long int by a
long int, the result is a long int. The cast is an attempt to convert a
long int into a long int - a NOP if ever there was one!

You have four reasonable courses of action:

1: use the cast to suppress the warning - this is the worst option, because
you're muddying the code to cater to a compiler's whim. This damages
readability and maintainability; it is likely to confuse people.

2: put up with the warning - this is better than Option 1, but everyone
likes a clean compile if they can get one.

3: get the implementor to change the implementation so that it doesn't
issue this spurious diagnostic message - how good an option this is will
depend on the implementor; some implementors do not respond well to
criticism. By the way, you can't claim that it's a bug, because the
observable behaviour of the compiler does appear to be conforming in this
case. It's a quality of implementation (QoI) issue, not a conformance
issue.

4: use a better compiler - this is the option I would recommend in this
case, although Option 3 is certainly worth a try.
can l * 10L ever be int ?
No, never. 10L is a long int. Assuming that the multiplication is legal, we
have the following possibilities:

Type of l Conversion
long double 10L is converted to long double; l * 10L is long double
double 10L is converted to double; l * 10L is double
float 10L is converted to float; l * 10L is float
unsigned long 10L is converted to unsigned long; l * 10L is unsigned long
long No conversions are necessary; l * 10L is long int
unsigned int if LONG_MAX >= UINT_MAX, l is converted to long int, and
l * 10L is long int; otherwise, both operands are converted
to unsigned long int, and l * 10L is unsigned long int
int, short int,\
unsigned short, \
unsigned char, : l is promoted to long int, and l * 10L is long int
signed char, /
char /

(my boss says thats illegal)
He's right. In none of the above cases does the result of the expression
have type int, and an implementation that produces an int from a
multiplication involving a long int is not a conforming implementation.

<snip>

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Sep 27 '07 #8

P: n/a
On Sep 27, 3:06 pm, Richard Heathfield <r...@see.sig.invalidwrote:
Nothing he has said suggests anything of the sort. It is strictly a QoI
matter. A bug-free conforming implementation could legally produce that
diagnostic message, despite correct code and correct runtime behaviour.
I would still consider it a bug. It is possible for
a compiler to conform to the C standard, yet still
have bugs.

Sep 27 '07 #9

P: n/a
Heinrich Pumpernickel wrote:
what does this warning mean ?
#include <stdio.h>

int main()
{
long l = 100;

printf("l is %li\n", l * 10L);

return 0;
}
when i compile this program with lcc-win32 it prints

lcc -A -ansic -O long.c -o long.obj
Warning c:\tmp\long.c: 4 old-style function definition for 'main'
This warning is bogus and incorrect.
Warning c:\tmp\long.c: 4 missing prototype for 'main'
This warning is bogus and incorrect.
Warning c:\tmp\long.c: 4 'int main()' is a non-ANSI definition
This warning is bogus and incorrect.
Warning c:\tmp\long.c: 7 printf argument mismatch for format i.
Expected long int got int
This warning is bogus and incorrect.
0 errors, 4 warnings
warning 1-3: how to give prototype for main ?

warning 4: i gave it long int but it says it got int . even
'(long)l * 10L' gives same warning . how to cast this properly ?
is it safe to ignore ???
Complain to Jacob. His compiler is broken.
Sep 27 '07 #10

P: n/a
Richard Heathfield <rj*@see.sig.invalidwrites:
Keith Thompson said:
>Heinrich Pumpernickel <la****@linuxmail.orgwrites:

<snip>
>>warning 4: i gave it long int but it says it got int . even
'(long)l * 10L' gives same warning . how to cast this properly ?
is it safe to ignore ???

<snip>
>It could be a bug in lcc-win32.

Nothing he has said suggests anything of the sort. It is strictly a QoI
matter. A bug-free conforming implementation could legally produce that
diagnostic message, despite correct code and correct runtime behaviour.
Perhaps we're using the word "bug" differently. There's no indication
that the compiler violates the standard. Nevertheless, if it produces
a diagnostic message claiming that the program passed an int to
printf, when in fact it passed a long, I call that a bug.

I suppose one could argue that only a violation of the standard should
be considered a "bug". But I note that the standard doesn't define,
or even use, that word, so I feel free to use it in what I think is a
reasonable manner.

--
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"
Sep 27 '07 #11

P: n/a
Keith Thompson said:
Richard Heathfield <rj*@see.sig.invalidwrites:
<snip>
>A bug-free conforming implementation could legally produce that
diagnostic message, despite correct code and correct runtime behaviour.

Perhaps we're using the word "bug" differently.
Perhaps. I've dealt with this matter elsethread. (Maybe you've read it by
now, so I won't bang on about it again.)

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Sep 27 '07 #12

P: n/a
Heinrich Pumpernickel wrote:
what does this warning mean ?
#include <stdio.h>

int main()
{
long l = 100;

printf("l is %li\n", l * 10L);

return 0;
}
when i compile this program with lcc-win32 it prints

lcc -A -ansic -O long.c -o long.obj
Warning c:\tmp\long.c: 4 old-style function definition for 'main'
Warning c:\tmp\long.c: 4 missing prototype for 'main'
Warning c:\tmp\long.c: 4 'int main()' is a non-ANSI definition
Warning c:\tmp\long.c: 7 printf argument mismatch for format i.
Expected long int got int
0 errors, 4 warnings
warning 1-3: how to give prototype for main ?

warning 4: i gave it long int but it says it got int . even
'(long)l * 10L' gives same warning . how to cast this properly ?
is it safe to ignore ???

gcc prints no warnings .

--
mfg, heinrich :)
Hi Heinrich!

1) Lcc-win does NOT print ANY warning at the standard warning level.
You invoked the option -A, that increases the warning level, and
produces in a few cases wrong warnings.
2) If you increase the warning level to its MAXIMUM, those warnings
are printed.
3) Note that int main() defines a function that will take an
unspecified number of arguments. It does NOT mean that it is
a void function. C is NOT C++. The first warning is justified
4) int main() is NOT a function prototype. Second warning is
justified.
5) The correct prototype is int main(void). Third warning is
justified. The ANSI C Norm specifies explicitely that.
6) The next warning is unjustified. The compiler has transformed
the type 'long' in type int internally, since in this particular
implementation sizeof(long) == sizeof(int). I will supress this
warning in the next version. The compiler will NOT warn
when you write "%li" and you give it an int either, but that
is a smaller problem.

Many people will tell you here that gcc is a better compiler
than lcc-win. This is true for a number of features. Lcc-win is
a small compiler that can't compete with either MSVC or gcc.
jacob
Sep 27 '07 #13

P: n/a
Heinrich Pumpernickel wrote:
[snip]
gcc prints no warnings .

gcc misses a warning for an incorrect definition
of the 'main' function then.
Sep 27 '07 #14

P: n/a
Martin Ambuhl wrote:
Heinrich Pumpernickel wrote:
>what does this warning mean ?
#include <stdio.h>

int main()
{
long l = 100;

printf("l is %li\n", l * 10L);

return 0;
}
when i compile this program with lcc-win32 it prints

lcc -A -ansic -O long.c -o long.obj
Warning c:\tmp\long.c: 4 old-style function definition for 'main'
This warning is bogus and incorrect.
Hi Ambuhl
You mean then that

int fn();

is the same as
int fn(void);

???

Note that

int fn() means a function with an UNSPECIFIED number of parameters!
>Warning c:\tmp\long.c: 4 missing prototype for 'main'
This warning is bogus and incorrect.
You mean then that

int fn() is a correct prototype?

This is completely WRONG.
>Warning c:\tmp\long.c: 4 'int main()' is a non-ANSI definition
This warning is bogus and incorrect.
The definition of main is int main(void) or int main(int,char **)
not int main()
>Warning c:\tmp\long.c: 7 printf argument mismatch for format i.
Expected long int got int
This warning is bogus and incorrect.
There. You have at least one hit!

Congratulations Mr Ambuhl. 1 out of 4 is quite a good progress for you.
Next time you will achive 2 wrongs for 2 correct. Keep on.

Sep 27 '07 #15

P: n/a
Martin Ambuhl <ma*****@earthlink.netwrites:
Heinrich Pumpernickel wrote:
>what does this warning mean ?
#include <stdio.h>
int main()
{
long l = 100;
printf("l is %li\n", l * 10L);
return 0;
}
when i compile this program with lcc-win32 it prints
lcc -A -ansic -O long.c -o long.obj
Warning c:\tmp\long.c: 4 old-style function definition for 'main'
This warning is bogus and incorrect.
>Warning c:\tmp\long.c: 4 missing prototype for 'main'
This warning is bogus and incorrect.
>Warning c:\tmp\long.c: 4 'int main()' is a non-ANSI definition
This warning is bogus and incorrect.
Well, partly. It certainly isn't "non-ANSI" (though why the messages
refer to ANSI rather than ISO is a mystery). But 'int main()' rather
than 'int main(void)' is an old-style declaration, and C99 6.11.6
says:

The use of function declarators with empty parentheses (not
prototype-format parameter type declarators) is an obsolescent
feature.
>Warning c:\tmp\long.c: 7 printf argument mismatch for format i.
Expected long int got int
This warning is bogus and incorrect.
Agreed.

[...]
Complain to Jacob. His compiler is broken.
Well, it has a bug.

--
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"
Sep 27 '07 #16

P: n/a
Martin Ambuhl wrote, On 27/09/07 06:52:
Heinrich Pumpernickel wrote:
>what does this warning mean ?
#include <stdio.h>

int main()
<snip>
>when i compile this program with lcc-win32 it prints

lcc -A -ansic -O long.c -o long.obj
Warning c:\tmp\long.c: 4 old-style function definition for 'main'
This warning is bogus and incorrect.
It may be bogus, but it is in fact (almost) correct. Not specifying void
for an empty parameter list makes it an old-style declaration rather
than a prototype. It is, of course, also a definition as well as a
declaration.

I agree completely with the rest of your points.

<snip>
>warning 4: i gave it long int but it says it got int . even
'(long)l * 10L' gives same warning . how to cast this properly ?
is it safe to ignore ???

Complain to Jacob. His compiler is broken.
Either that or the code posted here is not the code that was compiled.
--
Flash Gordon
Sep 27 '07 #17

P: n/a
Keith Thompson said:
Martin Ambuhl <ma*****@earthlink.netwrites:
<snip>
>>
>>Warning c:\tmp\long.c: 4 'int main()' is a non-ANSI definition
This warning is bogus and incorrect.

Well, partly. It certainly isn't "non-ANSI" (though why the messages
refer to ANSI rather than ISO is a mystery). But 'int main()' rather
than 'int main(void)' is an old-style declaration, and C99 6.11.6
says:

The use of function declarators with empty parentheses (not
prototype-format parameter type declarators) is an obsolescent
feature.
Indeed. Nevertheless, it remains a feature.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Sep 27 '07 #18

P: n/a
Martin Ambuhl said:
Heinrich Pumpernickel wrote:
>what does this warning mean ?
#include <stdio.h>

int main()
{
long l = 100;

printf("l is %li\n", l * 10L);

return 0;
}
when i compile this program with lcc-win32 it prints

lcc -A -ansic -O long.c -o long.obj
Warning c:\tmp\long.c: 4 old-style function definition for 'main'
This warning is bogus and incorrect.
It's bogus, but not incorrect: int main() is indeed an old-style function
definition, and in any case any implementation can issue any diagnostics
it likes.
>Warning c:\tmp\long.c: 4 missing prototype for 'main'
This warning is bogus and incorrect.
It's bogus, but not incorrect: int main() is not a prototype, so the
prototype for main (which is not required) is indeed missing, and in any
case any implementation can issue any diagnostics it likes. In this case,
it's a bit like saying "you didn't #include <signal.h>" - i.e. true but,
for the given code, silly.
>Warning c:\tmp\long.c: 4 'int main()' is a non-ANSI definition
This warning is bogus and incorrect.
Agreed.
>Warning c:\tmp\long.c: 7 printf argument mismatch for format i.
Expected long int got int
This warning is bogus and incorrect.
Agreed.
Complain to Jacob. His compiler is broken.
Agreed.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Sep 27 '07 #19

P: n/a
jacob navia wrote:
Heinrich Pumpernickel wrote:
[snip]
>gcc prints no warnings .


gcc misses a warning for an incorrect definition
of the 'main' function then.
What's incorrect about the main() definition?

You're correct that the only valid prototypes are int main(void) or int
main(int, char**). A prototype is not /required/ to be provided, however.

int main() is ugly and obsolescent. But it is not (yet) incorrect.

--
Philip Potter pgp <atdoc.ic.ac.uk
Sep 27 '07 #20

P: n/a
jacob navia <ja***@jacob.remcomp.frwrites:
[...]
3) Note that int main() defines a function that will take an
unspecified number of arguments. It does NOT mean that it is
a void function. C is NOT C++. The first warning is justified
In a function declaration that's not a definition, empty parentheses
indicate that the function takes an unspecified number and type of
arguments. But in a function *definition*, empty parentheses imply
that the function has no parameters.
4) int main() is NOT a function prototype. Second warning is
justified.
5) The correct prototype is int main(void). Third warning is
justified. The ANSI C Norm specifies explicitely that.
Just out of curiosity, why do you refer to ANSI C rather than ISO C?
The current C standard, C99, was issued by ISO; ANSI merely adopted
it.

There's a convoluted argument (I don't recall the details) that
'int main() { ... }' is invalid, but the general consensus is that
it's perfectly valid (though obsolescent).

[...]

--
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"
Sep 27 '07 #21

P: n/a
On Sep 27, 8:36 am, jacob navia <ja...@jacob.remcomp.frwrote:
Martin Ambuhl wrote:
Heinrich Pumpernickel wrote:
what does this warning mean ?
#include <stdio.h>
int main()
{
long l = 100;
printf("l is %li\n", l * 10L);
return 0;
}
when i compile this program with lcc-win32 it prints
lcc -A -ansic -O long.c -o long.obj
Warning c:\tmp\long.c: 4 old-style function definition for 'main'
This warning is bogus and incorrect.

Hi Ambuhl
You mean then that

int fn();

is the same as
int fn(void);

???

Note that

int fn() means a function with an UNSPECIFIED number of parameters!
But that wasn't what was in the original code. The original code went:

int main()
{
...
}

In a function DEFINITION like this, () is completely equivalent to
(void) (I remember looking it up once...)

You're right that in a DECLARATION, they are different:

int main(); /* main takes an unspecified number of parameters */
int main(void); /* main takes no parameters */

So the warning is indeed bogus and incorrect. :)
>
Warning c:\tmp\long.c: 4 missing prototype for 'main'
This warning is bogus and incorrect.

You mean then that

int fn() is a correct prototype?

This is completely WRONG.
But a definition serves as a prototype. I'd expect this warning to
mean I'd called a function with no prototype in scope, which isn't the
case here.
>
Warning c:\tmp\long.c: 4 'int main()' is a non-ANSI definition
This warning is bogus and incorrect.

The definition of main is int main(void) or int main(int,char **)
not int main()
Exactly as above... in a DEFINITION, int main() is absolutely fine.
(As in just main() in C90.)
>
Warning c:\tmp\long.c: 7 printf argument mismatch for format i.
Expected long int got int
This warning is bogus and incorrect.

There. You have at least one hit!

Congratulations Mr Ambuhl. 1 out of 4 is quite a good progress for you.
Next time you will achive 2 wrongs for 2 correct. Keep on.
4 out of 4 and a gold sticker, I'd have said. :)

Sep 27 '07 #22

P: n/a
Fr************@googlemail.com wrote:
>
But that wasn't what was in the original code. The original code went:

int main()
{
...
}

In a function DEFINITION like this, () is completely equivalent to
(void) (I remember looking it up once...)
This is the definition of a function with an unspecified
number of arguments.
You're right that in a DECLARATION, they are different:

int main(); /* main takes an unspecified number of parameters */
int main(void); /* main takes no parameters */

So the warning is indeed bogus and incorrect. :)
I do not think so. But I am not a language lawyer.

But a definition serves as a prototype. I'd expect this warning to
mean I'd called a function with no prototype in scope, which isn't the
case here.
This means that main has no prototype since you did NOT
provide a prototype and main *IS* always called!
>>>Warning c:\tmp\long.c: 4 'int main()' is a non-ANSI definition
This warning is bogus and incorrect.
The definition of main is int main(void) or int main(int,char **)
not int main()

Exactly as above... in a DEFINITION, int main() is absolutely fine.
(As in just main() in C90.)
It is absolutely fine. It is just an obsolescent feature, and
if you do take the HIGHEST warning level you get that warning!

Do not like it?

Then call the compiler with no special warning level and you see no
warnings. Under the HIGHEST warning level I will warn about obsolescent
features. What's wrong with that?

Sep 27 '07 #23

P: n/a
Philip Potter wrote:
jacob navia wrote:
>Heinrich Pumpernickel wrote:
[snip]
>>gcc prints no warnings .


gcc misses a warning for an incorrect definition
of the 'main' function then.

What's incorrect about the main() definition?

You're correct that the only valid prototypes are int main(void) or int
main(int, char**). A prototype is not /required/ to be provided, however.

int main() is ugly and obsolescent. But it is not (yet) incorrect.
Under the highest warning level, a compiler should warn
about

int main()

since it is an obsolete syntax. Note that lcc-win does NOT
warn in the default warning level.
Sep 27 '07 #24

P: n/a
Keith Thompson <ks***@mib.orgwrote:
jacob navia <ja***@jacob.remcomp.frwrites:
[...]
5) The correct prototype is int main(void). Third warning is
justified. The ANSI C Norm specifies explicitely that.

Just out of curiosity, why do you refer to ANSI C rather than ISO C?
The current C standard, C99, was issued by ISO; ANSI merely adopted
it.
Even for the former Standard, jacob should refer to the ISO Standard.
ANSI should not be relevant to him, because he's a Frog.

Richard
Sep 27 '07 #25

P: n/a
jacob navia wrote:
Martin Ambuhl wrote:
>Heinrich Pumpernickel wrote:
>>what does this warning mean ?
#include <stdio.h>

int main()
{
long l = 100;

printf("l is %li\n", l * 10L);

return 0;
}
when i compile this program with lcc-win32 it prints

lcc -A -ansic -O long.c -o long.obj
Warning c:\tmp\long.c: 4 old-style function definition for 'main'
This warning is bogus and incorrect.

Hi Ambuhl
You mean then that

int fn();

is the same as
int fn(void);

???
No. Nowhere did I say that. Why would you even suggest that I "meant"
something that I did not in anyway address.
There is nothing to warn about.
There is nothing "old-style" about it.
The diagnostic is an editorial statement of personal preference on the
part of the compiler writer and suggests a problem where there is none.
The warning is bogus. It is wrong. While Jacob's compiler is free to
emit what ever bogus diagnostics it wants to, that it does so makes it
broken as far as any serious user is concerned.
>
Note that

int fn() means a function with an UNSPECIFIED number of parameters!
>>Warning c:\tmp\long.c: 4 missing prototype for 'main'
This warning is bogus and incorrect.

You mean then that

int fn() is a correct prototype?

This is completely WRONG.
>>Warning c:\tmp\long.c: 4 'int main()' is a non-ANSI definition
This warning is bogus and incorrect.

The definition of main is int main(void) or int main(int,char **)
not int main()
>>Warning c:\tmp\long.c: 7 printf argument mismatch for format i.
Expected long int got int
This warning is bogus and incorrect.

There. You have at least one hit!

Congratulations Mr Ambuhl. 1 out of 4 is quite a good progress for you.
Next time you will achive 2 wrongs for 2 correct. Keep on.
As usual, Jacob, you are full of it. If you continue to prove that you
are completely ignorant, you may convince us not to bother with
lcc-win32 as well.
>
Sep 27 '07 #26

P: n/a
Richard Bos wrote:
Keith Thompson <ks***@mib.orgwrote:
>jacob navia <ja***@jacob.remcomp.frwrites:
[...]
>>5) The correct prototype is int main(void). Third warning is
justified. The ANSI C Norm specifies explicitely that.
Just out of curiosity, why do you refer to ANSI C rather than ISO C?
The current C standard, C99, was issued by ISO; ANSI merely adopted
it.

Even for the former Standard, jacob should refer to the ISO Standard.
ANSI should not be relevant to him, because he's a Frog.

Richard
You are a typical slave of HMQ (her majesty the queen).

I am not a frog. I live in a country where some people
eat parts of frogs. "Nuance" :-)

Sep 27 '07 #27

P: n/a
jacob navia wrote:
Heinrich Pumpernickel wrote:
[snip]
>gcc prints no warnings .


gcc misses a warning for an incorrect definition
of the 'main' function then.
Ignore Jacob. He hasn't a clue.
Sep 27 '07 #28

P: n/a
rl*@hoekstra-uitgeverij.nl (Richard Bos) writes:
Keith Thompson <ks***@mib.orgwrote:
>jacob navia <ja***@jacob.remcomp.frwrites:
[...]
5) The correct prototype is int main(void). Third warning is
justified. The ANSI C Norm specifies explicitely that.

Just out of curiosity, why do you refer to ANSI C rather than ISO C?
The current C standard, C99, was issued by ISO; ANSI merely adopted
it.

Even for the former Standard, jacob should refer to the ISO Standard.
ANSI should not be relevant to him, because he's a Frog.
That kind of epithet is uncalled for.

--
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"
Sep 27 '07 #29

P: n/a
On Sep 27, 9:49 am, jacob navia <ja...@jacob.remcomp.frwrote:
Francine.Ne...@googlemail.com wrote:
But that wasn't what was in the original code. The original code went:
int main()
{
...
}
In a function DEFINITION like this, () is completely equivalent to
(void) (I remember looking it up once...)

This is the definition of a function with an unspecified
number of arguments.
You're right that in a DECLARATION, they are different:
int main(); /* main takes an unspecified number of parameters */
int main(void); /* main takes no parameters */
So the warning is indeed bogus and incorrect. :)

I do not think so. But I am not a language lawyer.
Do you think it might be a good idea to become a language lawyer if
you're maintaining a compiler? :)

I looked it up again:

(6.5.4.3) 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.
>
But a definition serves as a prototype. I'd expect this warning to
mean I'd called a function with no prototype in scope, which isn't the
case here.

This means that main has no prototype since you did NOT
provide a prototype and main *IS* always called!
(6.7.1) If the declarator includes a parameter type list... such a
declarator also serves as a function prototype for later calls to the
same function in the same translation unit.

Now you need to observe that the empty list is a list...
>
>>Warning c:\tmp\long.c: 4 'int main()' is a non-ANSI definition
This warning is bogus and incorrect.
The definition of main is int main(void) or int main(int,char **)
not int main()
Exactly as above... in a DEFINITION, int main() is absolutely fine.
(As in just main() in C90.)

It is absolutely fine. It is just an obsolescent feature, and
if you do take the HIGHEST warning level you get that warning!

Do not like it?

Then call the compiler with no special warning level and you see no
warnings. Under the HIGHEST warning level I will warn about obsolescent
features. What's wrong with that?
Nothing wrong with that, but why not say "int main() is obsolescent
syntax" (which has the benefit of being true), rather than "int
main()' is a non-ANSI definition" (which has the drawback of being
false)?

(Note well that obsolescent != obsolete.)

Sep 27 '07 #30

P: n/a
jacob navia <ja***@jacob.remcomp.frwrote:
Richard Bos wrote:
Keith Thompson <ks***@mib.orgwrote:
jacob navia <ja***@jacob.remcomp.frwrites:
[...]
5) The correct prototype is int main(void). Third warning is
justified. The ANSI C Norm specifies explicitely that.
Just out of curiosity, why do you refer to ANSI C rather than ISO C?
The current C standard, C99, was issued by ISO; ANSI merely adopted
it.
Even for the former Standard, jacob should refer to the ISO Standard.
ANSI should not be relevant to him, because he's a Frog.

You are a typical slave of HMQ (her majesty the queen).
And you are illiterate, where headers are concerned. I'm a subject of
Hare Majesteit de Koningin, not of Her Majesty the Queen.

(My point would have stood as strongly if _you_ had been a subject of
either: we're all in Europe, not in the USA. ANSI is irrelevant to both
of us.)

Richard
Sep 27 '07 #31

P: n/a
Richard Bos said:
jacob navia <ja***@jacob.remcomp.frwrote:
>Richard Bos wrote:
<snip>
>
Even for the former Standard, jacob should refer to the ISO Standard.
ANSI should not be relevant to him, because he's a Frog.

You are a typical slave of HMQ (her majesty the queen).

And you are illiterate, where headers are concerned.
Indeed he is.
I'm a subject of
Hare Majesteit de Koningin, not of Her Majesty the Queen.
Indeed you are.
>
(My point would have stood as strongly if _you_ had been a subject of
either: we're all in Europe,
Speak for yourself! :-)
not in the USA. ANSI is irrelevant to both of us.)
Technically you're correct, but I don't think it's really such a big deal.
ANSI were the first national standards body to produce a C standard, and
the first conforming compilers all claimed ANSI conformance, not ISO
conformance. K&R2 has "ANSI C" plastered over the cover. It's hardly
surprising if people refer to standard C as "ANSI C". I'd rather save
pickiness for where it matters - such as, for example, not classifying the
UK as part of Europe. The English Channel is there for a reason. :-)

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Sep 27 '07 #32

P: n/a
"Richard Heathfield" <rj*@see.sig.invalidschrieb im Newsbeitrag
news:_b******************************@bt.com...
I'd rather save
pickiness for where it matters - such as, for example, not classifying the
UK as part of Europe. The English Channel is there for a reason. :-)
You mean the Frensh Channel?

And believe it or nor, the UK is part of Europe, it is not a continent of
it's own and is even a member in the EU (still)

Bye, Jojo
Sep 27 '07 #33

P: n/a

"Joachim Schmitz" <no*********@schmitz-digital.deschrieb im Newsbeitrag
news:fd**********@online.de...
"Richard Heathfield" <rj*@see.sig.invalidschrieb im Newsbeitrag
news:_b******************************@bt.com...
>I'd rather save
pickiness for where it matters - such as, for example, not classifying
the
UK as part of Europe. The English Channel is there for a reason. :-)
You mean the Frensh Channel?

And believe it or nor, the UK is part of Europe, it is not a continent of
it's own and is even a member in the EU (still)
s/in/of/g

Bye, Jojo
Sep 27 '07 #34

P: n/a
Joachim Schmitz said:
"Richard Heathfield" <rj*@see.sig.invalidschrieb im Newsbeitrag
news:_b******************************@bt.com...
>I'd rather save
pickiness for where it matters - such as, for example, not classifying
the UK as part of Europe. The English Channel is there for a reason. :-)
You mean the Frensh Channel?
Nope. I can read a map, same as anyone, and on my map of the universe it is
clearly marked as the English Channel. I don't object to calling it the
South Sea, though, if you'd prefer to do that.
>
And believe it or nor, the UK is part of Europe, it is not a continent of
it's own and is even a member in the EU (still)
I'm glad you think so. Just so long as Europe stays on its side of the
water, you can think what you like. :-)

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Sep 27 '07 #35

P: n/a
Richard Heathfield <rj*@see.sig.invalidwrites:
Richard Bos said:
>jacob navia <ja***@jacob.remcomp.frwrote:
>>Richard Bos wrote:
<snip>
>>
Even for the former Standard, jacob should refer to the ISO Standard.
ANSI should not be relevant to him, because he's a Frog.

You are a typical slave of HMQ (her majesty the queen).

And you are illiterate, where headers are concerned.

Indeed he is.
"Indeed", you can't resist can you? If you are going to killfile Jacob
then have the strength of character not to bitch and whine about him on
other peoples replies. You are responsible for more OT preening and
strutting than all the rest that you complain so audibly about when
things don't go your way. Maybe it is time for the killfile to be dusted
off.
Sep 27 '07 #36

P: n/a
On Thu, 27 Sep 2007 08:07:23 +0000, Richard Heathfield wrote:
Keith Thompson said:
[unsnip]
>Martin Ambuhl <ma*****@earthlink.netwrites:
>>Heinrich Pumpernickel wrote:
what does this warning mean ?
#include <stdio.h>
int main()
{
long l = 100;
printf("l is %li\n", l * 10L);
return 0;
}
when i compile this program with lcc-win32 it prints
lcc -A -ansic -O long.c -o long.obj
Warning c:\tmp\long.c: 4 old-style function definition for 'main'
This warning is bogus and incorrect.

Warning c:\tmp\long.c: 4 missing prototype for 'main'
This warning is bogus and incorrect.

Warning c:\tmp\long.c: 4 'int main()' is a non-ANSI definition
This warning is bogus and incorrect.
Well, partly. It certainly isn't "non-ANSI" (though why the messages
refer to ANSI rather than ISO is a mystery). But 'int main()' rather
than 'int main(void)' is an old-style declaration, and C99 6.11.6
says:

The use of function declarators with empty parentheses (not
prototype-format parameter type declarators) is an obsolescent
feature.

Indeed. Nevertheless, it remains a feature.
Well, it doesn't make the third of those warnings correct, but it
does cause the first or the second of them non-bogus. I don't
think it is bogus to issue a warning for the use of obsolescent
features. (But issuing *both* warnings *is* bogus, as they say
almost exactly the same thing; and if the warning read "function
declarations with empty parentheses are an obsolescent feature" it
would be more useful.)
Anyway, the warning "printf argument mismatch for format i.
Expected long int got int" is totally wrong. It doesn't make lcc
broken by itself (the standard allows an implementation to issue
whatever diagnostics it likes, without even requiring them to be
true), it just hugely lowers the quality of implementation,
#ifdef FLAME
(but in the case of lcc-win32 it is difficult to make it much
lower than it would be, even without that spurious warning...)
#endif
but anyway lcc-win32 is broken for other reasons, too. (Choosing
an ISO C standard header at random, reading the one lcc-win32
provides, and failing to see anything wrong with it is not a very
easy task.)
--
Army1987 (Replace "NOSPAM" with "email")
A hamburger is better than nothing.
Nothing is better than eternal happiness.
Therefore, a hamburger is better than eternal happiness.

Sep 27 '07 #37

P: n/a
jacob navia wrote:
>
You mean then that

int fn();

is the same as
int fn(void);

???
That's not the situation for which the compiler
issued the misleading messages.

int fn() { return 0; )

and

int fn(void) { return 0; }

define the fn function identically, even though they
declare it differently.

In a response to Francine Neary you write of the
original `int main() { ... }' that
This is the definition of a function with an unspecified
number of arguments.
.... but that's wrong. The function is defined with no
arguments at all. It is declared as taking an unspecified
(fixed) number of arguments, but it is defined as taking
none. Would you maintain that

int main(argc, argv)
int argc;
char **argv;
{ ... }

.... is the definition of a function with an unspecified
number of arguments?

Or again, consider a program of two compilation units:

/* module 1 */
int f(void);
int g();
int main(void) { return f() + g(); }

/* module 2 */
int f() { return 0; }
int g(void) { return 0; }

Is there a conflict between the declarations in module 1
and the definitions in module 2? If you see any, please
cite the relevant passage(s) from the Standard.

--
Eric Sosman
es*****@ieee-dot-org.invalid
Sep 27 '07 #38

P: n/a
jacob navia wrote:
>
Under the highest warning level, a compiler should warn
about

int main()

since it is an obsolete syntax. Note that lcc-win does NOT
warn in the default warning level.
That is a reasonable goal, and I have no objection to
a compiler that issues a reasonable warning. But what would
you think of a compiler whose warning for this usage was

*** warning: possible loss of precision
or
*** warning: arguments to main() should be
declared `volatile'
or
*** warning: the Hundred Years' War actually
lasted 116 years

? I applaud the compiler's attempt to warn, but I deplore
its use of misleading or downright incorrect messages.

--
Eric Sosman
es*****@ieee-dot-org.invalid
Sep 27 '07 #39

P: n/a
jacob navia <ja***@jacob.remcomp.frwrites:
Fr************@googlemail.com wrote:
>>
But that wasn't what was in the original code. The original code went:

int main()
{
...
}

In a function DEFINITION like this, () is completely equivalent to
(void) (I remember looking it up once...)

This is the definition of a function with an unspecified
number of arguments.
You may have missed it because it is in the "wrong" place, but:

6.7.5.3 Function declarators (including prototypes)

states in paragraph 14:

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.
>You're right that in a DECLARATION, they are different:

int main(); /* main takes an unspecified number of parameters */
int main(void); /* main takes no parameters */

So the warning is indeed bogus and incorrect. :)

I do not think so. But I am not a language lawyer.
Is it not an important skill for a compiler writer?
>But a definition serves as a prototype. I'd expect this warning to
mean I'd called a function with no prototype in scope, which isn't the
case here.

This means that main has no prototype since you did NOT
provide a prototype
Here I am with you.

6.9.1 Function definitions

states in paragraph 7:

The declarator in a function definition specifies the name of the
function being defined and the identifiers of its parameters. If the
declarator includes a parameter type list, the list also specifies
the types of all the parameters; such a declarator also serves as a
function prototype for later calls to the same function in the same
translation unit. If the declarator includes an identifier list,139)
the types of the parameters shall be declared in a following
declaration list. In either case, the type of each parameter is
adjusted as described in 6.7.5.3 for a parameter type list; the
resulting type shall be an object type.

This suggests to me that a function definition with no "parameter tpye
list" (note that int main() has an empty "identifier list" -- no the
same at all) is not a prototype. Given the special execption I quote
above it seems likely that this is a bug in the standard, but there it
is. I think you are right that int main() does not act as a prototype
for subsequent calls.
and main *IS* always called!
Ah, but that is not the meaning of "for later calls to the same
function in the translation unit". You would be right to complain
about:

int main()
{
return main();
}

because the subsequent call has no prototype.
>>>>Warning c:\tmp\long.c: 4 'int main()' is a non-ANSI definition
This warning is bogus and incorrect.
The definition of main is int main(void) or int main(int,char **)
not int main()

Exactly as above... in a DEFINITION, int main() is absolutely fine.
(As in just main() in C90.)
It is an ANSI definition. int main(void) is OK but so are equivalent
forms and they snuck in a phrase that makes int main() equivalent. At
least that is my reading of it.

--
Ben.
Sep 27 '07 #40

P: n/a
jacob navia <ja***@jacob.remcomp.frwrote:
Philip Potter wrote:
jacob navia wrote:
gcc misses a warning for an incorrect definition
of the 'main' function then.
What's incorrect about the main() definition?

You're correct that the only valid prototypes are int main(void) or int
main(int, char**). A prototype is not /required/ to be provided, however.

int main() is ugly and obsolescent. But it is not (yet) incorrect.

Under the highest warning level, a compiler should warn
about

int main()

since it is an obsolete syntax.
No, it isn't. It is obsolescent as a declaration. One may argue whether
it is obsolescent as the header of a _definition_ (you should really
know the difference) as well, but one cannot seriously argue that it is
already obsol_ete_, which is a rather stronger category than
obsol_escent_.
Note that lcc-win does NOT warn in the default warning level.
So to avoid this bug in your software we have to avoid getting a strong
level of error checking. Nice. Sounds like Microsoft-quality software.
Remember that bug where their own headers triggered a warning?

Richard
Sep 27 '07 #41

P: n/a
jacob navia wrote:
Philip Potter wrote:
>int main() is ugly and obsolescent. But it is not (yet) incorrect.

Under the highest warning level, a compiler should warn
about

int main()

since it is an obsolete syntax. Note that lcc-win does NOT
warn in the default warning level.
I agree with you (pretending for the moment you said "obsolescent" and not
"obsolete"). But you said:
>>gcc misses a warning for an incorrect definition
of the 'main' function then.
It should *not* issue a warning for incorrect syntax, because the syntax is not
incorrect. It can issue a warning for obsolescent syntax if it likes.

Phil

--
Philip Potter pgp <atdoc.ic.ac.uk
Sep 27 '07 #42

P: n/a
On Sep 27, 1:38 pm, Ben Bacarisse <ben.use...@bsb.me.ukwrote:
jacob navia <ja...@jacob.remcomp.frwrites:
This means that main has no prototype since you did NOT
provide a prototype

Here I am with you.

6.9.1 Function definitions

states in paragraph 7:

The declarator in a function definition specifies the name of the
function being defined and the identifiers of its parameters. If the
declarator includes a parameter type list, the list also specifies
the types of all the parameters; such a declarator also serves as a
function prototype for later calls to the same function in the same
translation unit. If the declarator includes an identifier list,139)
the types of the parameters shall be declared in a following
declaration list. In either case, the type of each parameter is
adjusted as described in 6.7.5.3 for a parameter type list; the
resulting type shall be an object type.

This suggests to me that a function definition with no "parameter tpye
list" (note that int main() has an empty "identifier list" -- no the
same at all) is not a prototype. Given the special execption I quote
above it seems likely that this is a bug in the standard, but there it
is. I think you are right that int main() does not act as a prototype
for subsequent calls.
As I explained elsewhere, I read this differently. The key sentence is
"If the declarator includes a parameter type list, the list also
specifies the types of all the parameters; such a declarator also
serves as a function prototype for later calls to the same function in
the same translation unit."

What does it mean to "include a parameter type list"? Well, the
Standard tells us, in 6.5.4.3! It differentiates between a parameter
type list, which "specifies the types of the parameters of a
function", and an identifier list, which "declares only the
identifiers of the parameters of a function".

The seemingly ambiguous case is int main() { ... }. This could either
be regarded as main with an empty parameter-type-list, or main with a
non-supplied optional identifier-list. Which is it? Well, 6.5.4.3
comes to the rescue again and clears this up for us: for a function
DEFINITION, an empty list of parameters is interpreted in the first
way, specifying that the function has no parameters. (As it happens,
in a declaration that isn't a definition, it's interpreted in the
second way, giving no information about parameters, but that's
irrelevant here.)

Therefore, in the definition int main() { ... }, () is the empty
parameter-type-list, and therefore it serves as a function prototype
for later calls to main.
>
and main *IS* always called!

Ah, but that is not the meaning of "for later calls to the same
function in the translation unit". You would be right to complain
about:

int main()
{
return main();

}

because the subsequent call has no prototype.
No, as above.
>
>>>Warning c:\tmp\long.c: 4 'int main()' is a non-ANSI definition
This warning is bogus and incorrect.
The definition of main is int main(void) or int main(int,char **)
not int main()
Exactly as above... in a DEFINITION, int main() is absolutely fine.
(As in just main() in C90.)

It is an ANSI definition. int main(void) is OK but so are equivalent
forms and they snuck in a phrase that makes int main() equivalent. At
least that is my reading of it.

--
Ben.

Sep 27 '07 #43

P: n/a
Fr************@googlemail.com wrote:
>
On Sep 27, 9:49 am, jacob navia <ja...@jacob.remcomp.frwrote:
[... "int main() { code }" versus "int main(void) { code } " ...]
But a definition serves as a prototype. I'd expect this warning to
mean I'd called a function with no prototype in scope, which isn't the
case here.
This means that main has no prototype since you did NOT
provide a prototype and main *IS* always called!

(6.7.1) If the declarator includes a parameter type list... such a
declarator also serves as a function prototype for later calls to the
same function in the same translation unit.

Now you need to observe that the empty list is a list...
[...]

Well, is my compiler broken then?

==========
#include <stdio.h>

int foo()
{
return 1;
}

int main(void)
{
foo();
foo(10);
}
==========

I get no warnings, even with warnings at the max. If I change the
"int foo()" to "int foo(void)", it warns me (even at the default
warning level) that "foo: declared with 'void' parameter list". If
you are saying that "int foo() { code }" does, in fact, prototype
foo() as having no parameters, then shouldn't my compiler warn me
about it, as it does when I explicitly state the void parameter list?

Now, I'm certainly not claiming that my compiler's output is the
gospel, just food for thought.

I'm curious what gcc with the "turn pedantry to the max" set of
switches says about the above?

--
+-------------------------+--------------------+-----------------------+
| Kenneth J. Brody | www.hvcomputer.com | #include |
| kenbrody/at\spamcop.net | www.fptech.com | <std_disclaimer.h|
+-------------------------+--------------------+-----------------------+
Don't e-mail me at: <mailto:Th*************@gmail.com>
Sep 27 '07 #44

P: n/a
Kenneth Brody wrote:
Fr************@googlemail.com wrote:
>On Sep 27, 9:49 am, jacob navia <ja...@jacob.remcomp.frwrote:

[... "int main() { code }" versus "int main(void) { code } " ...]
>>>But a definition serves as a prototype. I'd expect this warning to
mean I'd called a function with no prototype in scope, which isn't the
case here.
This means that main has no prototype since you did NOT
provide a prototype and main *IS* always called!
(6.7.1) If the declarator includes a parameter type list... such a
declarator also serves as a function prototype for later calls to the
same function in the same translation unit.

Now you need to observe that the empty list is a list...
[...]

Well, is my compiler broken then?

==========
#include <stdio.h>

int foo()
{
return 1;
}

int main(void)
{
foo();
foo(10);
}
==========

I get no warnings, even with warnings at the max. If I change the
"int foo()" to "int foo(void)", it warns me (even at the default
warning level) that "foo: declared with 'void' parameter list". If
you are saying that "int foo() { code }" does, in fact, prototype
foo() as having no parameters, then shouldn't my compiler warn me
about it, as it does when I explicitly state the void parameter list?

Now, I'm certainly not claiming that my compiler's output is the
gospel, just food for thought.

I'm curious what gcc with the "turn pedantry to the max" set of
switches says about the above?
Nothing!

[root@gateway tmp]# gcc -Wall -pedantic t12.c
t12.c: In function `main':
t12.c:12: warning: control reaches end of non-void function
[root@gateway tmp]#

Sep 27 '07 #45

P: n/a
Fr************@googlemail.com writes:
On Sep 27, 1:38 pm, Ben Bacarisse <ben.use...@bsb.me.ukwrote:
>jacob navia <ja...@jacob.remcomp.frwrites:
This means that main has no prototype since you did NOT
provide a prototype

Here I am with you.

6.9.1 Function definitions

states in paragraph 7:

The declarator in a function definition specifies the name of the
function being defined and the identifiers of its parameters. If the
declarator includes a parameter type list, the list also specifies
the types of all the parameters; such a declarator also serves as a
function prototype for later calls to the same function in the same
translation unit. If the declarator includes an identifier list,139)
the types of the parameters shall be declared in a following
declaration list. In either case, the type of each parameter is
adjusted as described in 6.7.5.3 for a parameter type list; the
resulting type shall be an object type.

This suggests to me that a function definition with no "parameter tpye
list" (note that int main() has an empty "identifier list" -- no the
same at all) is not a prototype. Given the special execption I quote
above it seems likely that this is a bug in the standard, but there it
is. I think you are right that int main() does not act as a prototype
for subsequent calls.

As I explained elsewhere, I read this differently. The key sentence is
"If the declarator includes a parameter type list, the list also
specifies the types of all the parameters; such a declarator also
serves as a function prototype for later calls to the same function in
the same translation unit."

What does it mean to "include a parameter type list"? Well, the
Standard tells us, in 6.5.4.3! It differentiates between a parameter
type list, which "specifies the types of the parameters of a
function", and an identifier list, which "declares only the
identifiers of the parameters of a function".

The seemingly ambiguous case is int main() { ... }. This could either
be regarded as main with an empty parameter-type-list, or main with a
non-supplied optional identifier-list. Which is it?
The syntax makes it quite clear, I think. See below...
>Well, 6.5.4.3
comes to the rescue again and clears this up for us: for a function
DEFINITION, an empty list of parameters is interpreted in the first
way, specifying that the function has no parameters.
Yes but that section does not tell us how to disambiguate the () in
the function definition -- it tell us what it *means* but not what is
*is*. In fact it is not ambiguous if you look at the syntax. A
parameter type list may not be empty whereas an identifier list can
be. (Check for yourself, readers, because the syntax is complex and I
may well have got that wrong, though I have checked as carefully as I
can.)

I am open to persuasion (that int foo() { ... } acts as a prototype)
but you will have to persuade the gcc people as well! -- OK you need
to ask for -Wstrict-prototypes, but at least you can.

--
Ben.
Sep 27 '07 #46

P: n/a
In article <_b******************************@bt.com>, Richard Heathfield
<rj*@see.sig.invalidwrites
>Joachim Schmitz said:
>"Richard Heathfield" <rj*@see.sig.invalidschrieb im Newsbeitrag
news:_b******************************@bt.com...
>>I'd rather save
pickiness for where it matters - such as, for example, not classifying
the UK as part of Europe. The English Channel is there for a reason. :-)
You mean the Frensh Channel?

Nope. I can read a map, same as anyone, and on my map of the universe it is
clearly marked as the English Channel. I don't object to calling it the
South Sea, though, if you'd prefer to do that.
>>
And believe it or nor, the UK is part of Europe, it is not a continent of
it's own and is even a member in the EU (still)

I'm glad you think so. Just so long as Europe stays on its side of the
water, you can think what you like. :-)
The sooner we get the Euro and fully integrated with Europe the better.
--
\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
\/\/\/\/\ Chris Hills Staffs England /\/\/\/\/
/\/\/ ch***@phaedsys.org www.phaedsys.org \/\/\
\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/

Sep 27 '07 #47

P: n/a
On Sep 27, 5:00 pm, Ben Bacarisse <ben.use...@bsb.me.ukwrote:
Francine.Ne...@googlemail.com writes:
On Sep 27, 1:38 pm, Ben Bacarisse <ben.use...@bsb.me.ukwrote:
jacob navia <ja...@jacob.remcomp.frwrites:
This means that main has no prototype since you did NOT
provide a prototype
Here I am with you.
6.9.1 Function definitions
states in paragraph 7:
The declarator in a function definition specifies the name of the
function being defined and the identifiers of its parameters. If the
declarator includes a parameter type list, the list also specifies
the types of all the parameters; such a declarator also serves as a
function prototype for later calls to the same function in the same
translation unit. If the declarator includes an identifier list,139)
the types of the parameters shall be declared in a following
declaration list. In either case, the type of each parameter is
adjusted as described in 6.7.5.3 for a parameter type list; the
resulting type shall be an object type.
This suggests to me that a function definition with no "parameter tpye
list" (note that int main() has an empty "identifier list" -- no the
same at all) is not a prototype. Given the special execption I quote
above it seems likely that this is a bug in the standard, but there it
is. I think you are right that int main() does not act as a prototype
for subsequent calls.
As I explained elsewhere, I read this differently. The key sentence is
"If the declarator includes a parameter type list, the list also
specifies the types of all the parameters; such a declarator also
serves as a function prototype for later calls to the same function in
the same translation unit."
What does it mean to "include a parameter type list"? Well, the
Standard tells us, in 6.5.4.3! It differentiates between a parameter
type list, which "specifies the types of the parameters of a
function", and an identifier list, which "declares only the
identifiers of the parameters of a function".
The seemingly ambiguous case is int main() { ... }. This could either
be regarded as main with an empty parameter-type-list, or main with a
non-supplied optional identifier-list. Which is it?

The syntax makes it quite clear, I think. See below...
Well, 6.5.4.3
comes to the rescue again and clears this up for us: for a function
DEFINITION, an empty list of parameters is interpreted in the first
way, specifying that the function has no parameters.

Yes but that section does not tell us how to disambiguate the () in
the function definition -- it tell us what it *means* but not what is
*is*. In fact it is not ambiguous if you look at the syntax. A
parameter type list may not be empty whereas an identifier list can
be. (Check for yourself, readers, because the syntax is complex and I
may well have got that wrong, though I have checked as carefully as I
can.)
I don't have the energy to figure it out, but I'll take your word for
it... especially since, re-reading 6.5.4.3 in context, it does seem
that "empty list" refers to an empty identifier list.

So that's really ugly :(

int main() { ... } and int main(void) { ... } do indeed have very
subtly different semantics, which is dumb: after seeing either of them
the compiler knows exactly the signature of main, but only in one case
is it allowed to use this knowledge if it encounters main later in the
same translation unit. Yuck!
>
I am open to persuasion (that int foo() { ... } acts as a prototype)
but you will have to persuade the gcc people as well! -- OK you need
to ask for -Wstrict-prototypes, but at least you can.

--
Ben.
Sep 27 '07 #48

P: n/a
On Thu, 27 Sep 2007 05:07:00 -0400, Martin Ambuhl wrote:
jacob navia wrote:
>Martin Ambuhl wrote:
>>Heinrich Pumpernickel wrote:
int main()
[...]
lcc -A -ansic -O long.c -o long.obj
Warning c:\tmp\long.c: 4 old-style function definition for 'main'
This warning is bogus and incorrect.
There is nothing "old-style" about it.
6.11.6 Function declarators
1 The use of function declarators with empty parentheses (not prototype-
format parameter type declarators) is an obsolescent feature.
6.11.7 Function definitions
1 The use of function definitions with separate parameter identifier and
declaration lists (not prototype-format parameter type and identifier
declarators) is an obsolescent feature.

() in a function definition is the type of function definition having a
parameter identifier list, not a parameter declaration list. This is
specified by the grammar. I suppose you could try to argue that "old
style" is not the same as obsolescent, but:

6.7.5.3 Function declarators (including prototypes)
15 For two function types to be compatible, both shall specify compatible
return types.125) [...]
125) If both function types are "old style", parameter types are not
compared.
Sep 27 '07 #49

P: n/a
Fr************@googlemail.com wrote:
I don't have the energy to figure it out, but I'll take your word for
it... especially since, re-reading 6.5.4.3 in context, it does seem
that "empty list" refers to an empty identifier list.

So that's really ugly :(

int main() { ... } and int main(void) { ... } do indeed have very
subtly different semantics, which is dumb: after seeing either of them
the compiler knows exactly the signature of main, but only in one case
is it allowed to use this knowledge if it encounters main later in the
same translation unit. Yuck!
>I am open to persuasion (that int foo() { ... } acts as a prototype)
but you will have to persuade the gcc people as well! -- OK you need
to ask for -Wstrict-prototypes, but at least you can.

--
Ben.
OK Ben, then, you agree that a warning at the highest warning
level is justified!
Sep 27 '07 #50

92 Replies

This discussion thread is closed

Replies have been disabled for this discussion.