problem with functions

E

Eric Sosman

Flash said:
jacob said:
Richard Heathfield a écrit :



Genius programmers like you should not use lcc-win32.


The better the programmer the less important the quality of the warning
since they are less likely to make the mistake [...]

This, I think, is not the case -- at least, it isn't for
me, although of course YMMV.

In the Very Old Days, I wrote programs by keypunching them,
wrapping the cards in a rubber band, and handing the deck through
a little window. Some hours later the deck would return to me
accompanied by a printout, and if I'd made some kind of foolish
mistake I had thereby lost one of my two or perhaps three daily
opportunities to try a compilation. Under those circumstances I
was *very* careful to desk-check before consigning my program to
its leisurely fate, because the "opportunity cost" of an error
was so very high. But nowadays? Pfui: I'll just dump a half-
written module through the compiler, knowing that it still has
errors but also knowing that the compiler will find them for me
faster than I would find them by eyeballing the file.

The gradual improvement in warnings has also made me sloppier
than I used to be. When I started writing C some thirty years
ago, I already had the luxury of fairly quick turn-around and had
begun to become less diligent about desk-checking my stuff. Yet
I soon learned that it was still necessary to be scrupulous about
certain parts of the language, one of them being the matching up
of arguments. The compilers of that day were perfectly happy to
accept `printf("d%\n", sqrt(x))' or `printf("%d\n", sqrt(x))' or
even `fprintf("%f\n", sqrt(x))', and it was only at run-time that
you'd get a clue something might be wrong. Quick compile-edit-
recompile cycles relieved some of the pressure to get things right
the very first time, but I was still maniacal about checking my
format strings, or more generally, my function arguments.

Then along came prototypes, and suddenly the compilers started
catching many of the errors I was still on guard against, like the
fprintf() above. And at more or less the same time, compilers
began to be able to diagnose the errors in the above printf()s, too.
And since I'm fundamentally lazy, I happily let the compilers take
care of these matters for me, and lost the rigid habits of my early
training. I believe that I am nowadays *more* likely to make some
kinds of errors (confident that the compiler will catch them cheaply)
than I was when I was less proficient (but operated without a net).
and more likely to be ale
to work out why there was a diagnostic. So it is actually
inexperienced/poor programmers who should avoid lcc-win32.

Agreed, on both points. Experience helps one to unravel a
baffling outcome, whether it be an obfuscated warning or a nonsense
output. When a warning is as poor -- as downright r-o-n-g, when
it comes to that -- as the one Jacob illustrated, a scarred veteran
will sort things out quickly but a neophyte will be nonplussed.
The beginner is, I think, better served by no warnings at all than
by bad ones -- at least, it worked for me.
 
F

Flash Gordon

Eric said:
Flash said:
jacob said:
Richard Heathfield a écrit :


Not true. I use gcc, which produces a diagnostic message for a
mismatch between printf format specifier and argument type, and yet
there are not "many such warnings" when I use it to compile my code,
and so the really important messages do not in fact get lost,
despite your claim to the contrary.


Genius programmers like you should not use lcc-win32.


The better the programmer the less important the quality of the
warning since they are less likely to make the mistake [...]

This, I think, is not the case -- at least, it isn't for
me, although of course YMMV.

The gradual improvement in warnings has also made me sloppier
than I used to be. When I started writing C some thirty years
ago, I already had the luxury of fairly quick turn-around and had
begun to become less diligent about desk-checking my stuff. Yet

> Then along came prototypes, and suddenly the compilers started
> catching many of the errors I was still on guard against, like the
> fprintf() above. And at more or less the same time, compilers
> began to be able to diagnose the errors in the above printf()s, too.
> And since I'm fundamentally lazy, I happily let the compilers take

Yes, but the inexperienced were not driven up to the level of care you
used to take. So although you may be more likely to make such mistakes
now than in days of yaw, you are probably still less likely to make them
than the inexperienced programmer.

Agreed, on both points. Experience helps one to unravel a
baffling outcome, whether it be an obfuscated warning or a nonsense
output. When a warning is as poor -- as downright r-o-n-g, when
it comes to that -- as the one Jacob illustrated, a scarred veteran
will sort things out quickly but a neophyte will be nonplussed.
The beginner is, I think, better served by no warnings at all than
by bad ones -- at least, it worked for me.

Indeed.

In my case it was the half hour to erase an EPROM followed by the hassle
of transferring the program to the programmer and programming the EPROM
that made me take rather more care. That and having to get a HW engineer
to set up the logic analyser for me so I could see what the program was
doing...

This was back when I was writing assembler.
 
J

jacob navia

I fixed those warnings Eric, as you suggested in another post:
With higher warning level, I emit warnings for
%d --> pointer (any pointer)
%ld --> integer

jacob
 
E

Eric Sosman

jacob navia wrote On 05/25/06 12:42,:
I fixed those warnings Eric, as you suggested in another post:
With higher warning level, I emit warnings for
%d --> pointer (any pointer)
%ld --> integer

Sounds good. It's important for portability's sake
not to be fooled by the coincidences of a particular
implementation, because those coincidences may not apply
to the next one. `long' and `int' are distinct types,
even if (on some systems) they happen to behave the same
way. `long double' and `double' are distinct, `char*'
and `int*' are distinct -- even `char*' and `void*' are
different types. By issuing good diagnostics, a compiler
can help keep the programmer aware of such distinctions,
and thus make porting less of a nightmare than it has
too often been.
 
K

Keith Thompson

jacob navia said:
Keith Thompson a écrit : [...]
So you don't issue a warning for an attempt to print a pointer with
"%d"?
Printing a pointer with "%d" may happen to work on your particular
implementation, but it's wrong. That's what "%p" is for.
gcc gets this right. lcc-win32 should do so as well.

OK OK you are right. I have added warnings for mismatch with long/int,
and with mismatches pointer/int. This will appear only if you increase
the warning level or if you ask for the "code check" option in the IDE

That's certainly an improvement.

This doesn't affect me, since I don't use lcc-win32, but I strongly
recommend that you issue these warnings *by default*. If I were using
lcc-win32, there would be very nearly *no* circumstances in which I
wouldn't want it to warn me about this kind of argument mismatch.
 
R

Robert Latest

On Thu, 25 May 2006 01:47:29 +0200,
in Msg. said:
I do not encourage "non portable code", I just do not want to bother my
users you see?

Maybe you don't, but a compiler that doesn't warn on

printf("%lu", 3);

encourages the proliferation of non-portable code. People who *want* to
write non-portable code can turn off compiler warnings or redirect
stderr to /dev/null when compiling.

robert
 
J

jacob navia

Robert Latest a écrit :
On Thu, 25 May 2006 01:47:29 +0200,



Maybe you don't, but a compiler that doesn't warn on

printf("%lu", 3);

encourages the proliferation of non-portable code. People who *want* to
write non-portable code can turn off compiler warnings or redirect
stderr to /dev/null when compiling.

robert

OK, I have added that warning when you use an increased warning
level.
jacob
 
K

Keith Thompson

jacob navia said:
Robert Latest a écrit :

OK, I have added that warning when you use an increased warning
level.

So the default behavior is to warn only about things that matter for
code that is to be compiled only under lcc-win32, and you have to turn
up the warning level to get warnings about non-portable code.

If that doesn't encourage non-portable code, I don't know what does.
 
J

jacob navia

Keith Thompson a écrit :
So the default behavior is to warn only about things that matter for
code that is to be compiled only under lcc-win32, and you have to turn
up the warning level to get warnings about non-portable code.

If that doesn't encourage non-portable code, I don't know what does.

If you want all warnings you just check a box in the IDE.

NOT very difficult to do.

A philosophical question is what the default behavior should be.

I think that is the best to give as little warnings as possible in the
default mode. Maybe I haven't followed this in all cases but I have
moved most of non-critical warnings to the -A option when you
get all warnings for non-portable code.

What is a critical warning?

This for instance:
int fn(void)
{
}

You get
Warning: tc.c: 3 Missing return value

This is critical because the program contains a serious flaw, it will
return a random value.
Code like

printf("%lu",3);

will fail in a 64 bit environment for instance, and I think you were
right when you complained about not warning about this at all.
But in a 32 bit environment it is not critical, it will work as
expected. This means that it should pass in the default mode.

The default mode is: all non-critical warnings are suppressed.
 
R

Richard Heathfield

jacob navia said:
The default mode is: all non-critical warnings are suppressed.

Yes, gcc seems to be like that, too - and it's a real nuisance, and whoever
made that stupid stupid stupid design decision needs a good kicking and an
introduction to Clint's LART. Whenever I compile a program in gcc I have to
do this:

gcc -W -Wall -ansi -pedantic -Wformat-nonliteral -Wcast-align
-Wpointer-arith -Wbad-function-cast -Wmissing-prototypes
-Wstrict-prototypes -Wmissing-declarations -Winline -Wundef
-Wnested-externs -Wcast-qual -Wshadow -Wconversion -Wwrite-strings
-Wno-conversion -ffloat-store -O2 -o foo foo.c

whereas I would prefer to do this:

gcc -o foo foo.c

and still get the same diagnostic quality.

Oh well - thank heaven for makefiles.
 
K

Keith Thompson

jacob navia said:
I think that is the best to give as little warnings as possible in the
default mode.

I have seldom seen a statement with which I disagree more strongly.

[...]
Code like

printf("%lu",3);

will fail in a 64 bit environment for instance, and I think you were
right when you complained about not warning about this at all.
But in a 32 bit environment it is not critical, it will work as
expected. This means that it should pass in the default mode.

That code invokes undefined behavior in *all* environments. In some
environments, the undefined behavior happens to manifest itself by
working as if you has used the proper "%d".

This is a subtle error that's difficult to detect because it's masked
by the compiler (deliberately at compilation time, accidentally at
execution time). You're not doing your users any favors by failing to
tell them about such problems. And this kind of thing is so easy to
get right.

int and long are two distinct types, even if they happen to be the
same size. signed int and unsigned int are two distinct types, even
though they happen to be the same size.
The default mode is: all non-critical warnings are suppressed.

Another reason not to use lcc-win32.
 
C

CBFalconer

Keith said:
So the default behavior is to warn only about things that matter for
code that is to be compiled only under lcc-win32, and you have to
turn up the warning level to get warnings about non-portable code.

If that doesn't encourage non-portable code, I don't know what does.

The problem isn't so much with failure to warn about this or that
particular error, but the sloppy attitude that built a system
without those warnings in the first place. This is the sort of
thing that does Jacobs reputation little good.

--
"If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson
More details at: <http://cfaj.freeshell.org/google/>
Also see <http://www.safalra.com/special/googlegroupsreply/>
 
C

CBFalconer

Richard said:
jacob navia said:


Yes, gcc seems to be like that, too - and it's a real nuisance,
and whoever made that stupid stupid stupid design decision needs
a good kicking and an introduction to Clint's LART. Whenever I
compile a program in gcc I have to do this:

gcc -W -Wall -ansi -pedantic -Wformat-nonliteral -Wcast-align
-Wpointer-arith -Wbad-function-cast -Wmissing-prototypes
-Wstrict-prototypes -Wmissing-declarations -Winline -Wundef
-Wnested-externs -Wcast-qual -Wshadow -Wconversion -Wwrite-strings
-Wno-conversion -ffloat-store -O2 -o foo foo.c

whereas I would prefer to do this:

gcc -o foo foo.c

and still get the same diagnostic quality.

Oh well - thank heaven for makefiles.

I just use an alias.

--
"If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson
More details at: <http://cfaj.freeshell.org/google/>
Also see <http://www.safalra.com/special/googlegroupsreply/>
 
J

jaysome

jacob navia said:


Yes, gcc seems to be like that, too - and it's a real nuisance, and whoever
made that stupid stupid stupid design decision needs a good kicking and an
introduction to Clint's LART. Whenever I compile a program in gcc I have to
do this:

gcc -W -Wall -ansi -pedantic -Wformat-nonliteral -Wcast-align
-Wpointer-arith -Wbad-function-cast -Wmissing-prototypes
-Wstrict-prototypes -Wmissing-declarations -Winline -Wundef
-Wnested-externs -Wcast-qual -Wshadow -Wconversion -Wwrite-strings
-Wno-conversion -ffloat-store -O2 -o foo foo.c

whereas I would prefer to do this:

gcc -o foo foo.c

Very good. But you could go a step further:

gcc foo # assumes compiling foo.c, and outputs name without extension
 
D

Dann Corbit

jacob navia said:
Eric Sosman a écrit :

I was speaking about %d, %u. In this case we have:

D:\lcc\mc63\test>type twp.c
#include <stdio.h>
int main(void)
{
printf ("%d = %s\n", "The Answer", 42);
}

D:\lcc\mc63\test>lcc twp.c
Warning twp.c: 4 printf argument mismatch for format s. Expected char
pointer got int
0 errors, 1 warning

D:\lcc\mc63\test>

Note that printing a pointer with %d is still allowed. %s needs a char
pointer however, it is not symmetric.

I thought printing a pointer required:
1. A cast to (void *) if not already of that type
2. Using the %p format specifier.
 
K

Keith Thompson

Dann Corbit said:
I thought printing a pointer required:
1. A cast to (void *) if not already of that type
2. Using the %p format specifier.

It does. jacob is referring to the behavior of lcc-win32, which
issues warnings for some format string mismatches, but apparently
doesn't complain about using "%d" to print a pointer. (Such a warning
is not required, of course.)
 

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

Members online

Forum statistics

Threads
473,774
Messages
2,569,598
Members
45,151
Latest member
JaclynMarl
Top