what does this warning mean ?

  • Thread starter Heinrich Pumpernickel
  • Start date

H

Heinrich Pumpernickel

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 .
 
Ad

Advertisements

R

Richard Heathfield

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.
 
K

Keith Thompson

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 ?

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.
 
R

Richard Heathfield

Keith Thompson said:

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.
 
E

Eric Sosman

Heinrich 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

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?
 
H

Heinrich Pumpernickel

Heinrich Pumpernickel said:


change int main() to int main(void)


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.


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)
 
Ad

Advertisements

P

pete

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.
 
R

Richard Heathfield

Heinrich Pumpernickel said:

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>
 
O

Old Wolf

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.
 
R

Richard Heathfield

Old Wolf said:
I would still consider it a bug.

If it were my implementation, I'd agree.
It is possible for a compiler to conform to the C standard, yet still
have bugs.

Indeed. Nevertheless, whether a particular (conforming) behaviour
constitutes a bug depends on whether the behaviour is intentional, and who
can know that, apart from the person or people who specified the behaviour
in the first place? If the implementation's spec says "if they try to
multiply a long int by a long int in a printf argument expression and then
print it with %li, Do The Right Thing in terms of output, but produce a
silly, confusing, and preferably misleading warning just to mess with
their heads" and if that spec accurately reflects the intent of the
specifier, then it's not a bug in the implementation.
 
M

Martin Ambuhl

Heinrich 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'
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.
 
Ad

Advertisements

K

Keith Thompson

Richard Heathfield said:
Keith Thompson said:



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.
 
F

Flash Gordon

Martin Ambuhl wrote, On 27/09/07 06:52:
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.

Complain to Jacob. His compiler is broken.

Either that or the code posted here is not the code that was compiled.
 
R

Richard Heathfield

Keith Thompson said:
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.)
 
J

jacob navia

Heinrich 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 ?

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 .

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
 
Ad

Advertisements

J

jacob navia

Martin said:
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!
This warning is bogus and incorrect.

You mean then that

int fn() is a correct prototype?

This is completely WRONG.
This warning is bogus and incorrect.

The definition of main is int main(void) or int main(int,char **)
not int main()
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.
 
K

Keith Thompson

Martin Ambuhl said:
This warning is bogus and incorrect.

This warning is bogus and incorrect.

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.
 
R

Richard Heathfield

Keith Thompson said:
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.[/QUOTE]

Indeed. Nevertheless, it remains a feature.
 
Ad

Advertisements

P

Philip Potter

jacob said:
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.
 

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


Top