[comp.lang.c] impossible problem for find

karl@haddock.UUCP (Karl Heuer) (04/29/87)

In article <5797@brl-smoke.ARPA> gwyn@brl.arpa (Doug Gwyn) writes:
[source for program "newer", ending with]
>#ifdef lint
>	return file1.st_mtime < file2.st_mtime ? 1 : 0;
>#else
>	EXIT( file1.st_mtime < file2.st_mtime ? 1 : 0 );
>#endif

I don't mean to flame the author's style, but what's wrong with
	EXIT( file1.st_mtime < file2.st_mtime ? 1 : 0 );
	/* NOTREACHED */
?  That's what the lintpragma is for.

Karl W. Z. Heuer (ima!haddock!karl or karl@haddock.isc.com), The Walking Lint

ken@rochester.UUCP (04/30/87)

|I don't mean to flame the author's style, but what's wrong with
|	EXIT( file1.st_mtime < file2.st_mtime ? 1 : 0 );
|	/* NOTREACHED */

Or better still:

	EXIT( file1.st_mtime < file2.st_mtime);
	/*NOTREACHED*/

	Ken

gwyn@brl-smoke.ARPA (Doug Gwyn ) (04/30/87)

In article <465@haddock.UUCP> karl@haddock.ISC.COM.UUCP (Karl Heuer) writes:
-I don't mean to flame the author's style, but what's wrong with
-	EXIT( file1.st_mtime < file2.st_mtime ? 1 : 0 );
-	/* NOTREACHED */
-?  That's what the lintpragma is for.

Because it doesn't work.  The main() function then fails to return a value,
and lint detects that (or at least it CAN detect that if it's smart enough).

gwyn@brl-smoke.ARPA (Doug Gwyn ) (04/30/87)

In article <27409@rochester.ARPA> ken@rochester.UUCP (Ken Yap) writes:
>|	EXIT( file1.st_mtime < file2.st_mtime ? 1 : 0 );
>Or better still:
>	EXIT( file1.st_mtime < file2.st_mtime);

No, there are two major reasons for writing the first form:
	(1) The "newer" utility returns a variety of integer codes.
	By making the 1 and 0 values explicit (as well as the 2 value
	earlier), it is easier to see precisely what is returned.
	(2) I try to uniformly handle Boolean expressions as Booleans,
	not as integers.  I find this practice leads to more reliable
	code in the long run.
A minor reason is that any reasonable optimizer will generate the same
code in either case, not that efficiency is important here.

rbutterworth@orchid.UUCP (05/01/87)

In article <5815@brl-smoke.ARPA>, gwyn@brl-smoke.ARPA (Doug Gwyn ) writes:
> In article <465@haddock.UUCP> karl@haddock.ISC.COM.UUCP (Karl Heuer) writes:
> > I don't mean to flame the author's style, but what's wrong with
> >     EXIT( file1.st_mtime < file2.st_mtime ? 1 : 0 );
> >     /* NOTREACHED */
> Because it doesn't work.  The main() function then fails to return a value,
> and lint detects that (or at least it CAN detect that if it's smart enough).

But if lint smart enough, it should know that main actually fails to return
at all, which is quite a different thing from returning but failing to return
a value.

gwyn@brl-smoke.ARPA (Doug Gwyn ) (05/03/87)

In article <7215@orchid.UUCP> rbutterworth@orchid.UUCP writes:
-In article <5815@brl-smoke.ARPA>, gwyn@brl-smoke.ARPA (Doug Gwyn ) writes:
-> Because it doesn't work.  The main() function then fails to return a value,
-> and lint detects that (or at least it CAN detect that if it's smart enough).
-But if lint smart enough, it should know that main actually fails to return
-at all, which is quite a different thing from returning but failing to return
-a value.

I said what I meant.  I did not say that the main() function returned.
Lint warns about an int-valued function that doesn't return an int value.
main() is an int-valued function.  Why do I have to spell this out?

karl@haddock.UUCP (Karl Heuer) (05/04/87)

In article <5824@brl-smoke.ARPA> gwyn@brl.arpa (Doug Gwyn (VLD/VMB) <gwyn>) writes:
>I said what I meant.  I did not say that the main() function returned.
>Lint warns about an int-valued function that doesn't return an int value.
>main() is an int-valued function.  Why do I have to spell this out?

Let's rephrase.  There are three types of function under consideration: "int",
"void", and "dead".  The last refers to a function that never returns at all,
such as exit(), longjmp(), and dpANS abort(); unfortunately C has no explicit
declaration for this.

You seem to be saying that it is incorrect to have a dead function declared
int.  I disagree, because I think the acting definition of an int function is
"all return paths return an int type"; this is vacuously true in the case of a
dead function.  (Note that the generalization of this implies that *any*
declaration would be valid, except that main() by definition is supposed to be
declared int.)

It is quite possible that some versions of lint disagree with me here, and
insist that dead functions be declared void.  Does yours complain, or is this
a theoretical argument?  (Most versions of lint -- and X3J11, as of May86 --
don't even insist that void functions be declared void.)

I would hope that such a lint would make an exception for main(), since it's
so common.  And it's *not* an error to never return from main()!

Karl W. Z. Heuer (ima!haddock!karl or karl@haddock.isc.com), The Walking Lint

karl@haddock.UUCP (Karl Heuer) (05/04/87)

In article <474@haddock.UUCP> karl@haddock.ISC.COM.UUCP (Karl Heuer) writes:
>(Most versions of lint -- and X3J11, as of May86 -- don't even insist that
>void functions be declared void.)

I suppose I should clarify this.  The first "void" means "logically void",
i.e. a function with no return value; the second refers to the actual
declaration.  For example, "int nullf() {}" is acceptable to the lint I just
tried, and is still legitimate in X3J11 unless they've changed recently.

(In my opinion, it should be retained for backward compatibility, but should
be marked as deprecated.)

Karl W. Z. Heuer (ima!haddock!karl or karl@haddock.isc.com), The Walking Lint

rbutterworth@orchid.UUCP (05/05/87)

In article <477@haddock.UUCP>, karl@haddock.UUCP (Karl Heuer) writes:
> In article <474@haddock.UUCP> karl@haddock.ISC.COM.UUCP (Karl Heuer) writes:
> I suppose I should clarify this.  The first "void" means "logically void",
> i.e. a function with no return value; the second refers to the actual
> declaration.  For example, "int nullf() {}" is acceptable to the lint I just
> tried, and is still legitimate in X3J11 unless they've changed recently.
> (In my opinion, it should be retained for backward compatibility, but should
> be marked as deprecated.)

One of the lints we use here (on GCOS8 (approaching ANSI)) treats
    int func1(int a) { printf("%d", a); return;}
        func2(int a) { printf("%d", a); return;}
quite differently.  func2() is perfectly valid (except for ignoring
the status returned by printf), but func1() causes a complaint that
it was explicitly declared int but fails to return a value.

Our modified BSD 4.3 lint has a /*GOTO*/ directive in the function
declaration that indicates that the function never returns.
e.g.  extern /*GOTO*/ exit();
The /*NOTREACHED*/ directive is thus never needed (it never was
very useful anyway since lint only gives warnings if you remember
to use it).  Such a directive really should be part of the language
though since it would let the compiler generate better code.

(And for those that have asked, no, our changes aren't yet in a form
where we could send them out easily.  Would anyone at Berkeley be
interested in them?)

gwyn@brl-smoke.UUCP (05/06/87)

In article <477@haddock.UUCP> karl@haddock.ISC.COM.UUCP (Karl Heuer) writes:
>...  For example, "int nullf() {}" is acceptable to the lint I just
>tried, and is still legitimate in X3J11 unless they've changed recently.

What X3J11 says is that any use by the caller of the return value of
such a function produces undefined behavior (as, logically, it should).
If the caller doesn't use the value, then it's legal portable C.

There are several versions of "lint", with different ideas of what
should be checked by default.  The one I usually use doesn't complain
about the above example (nor the original newer.c with /*NOTREACHED*/
after the last exit() call), but I would consider such a complaint
legitimate and therefore took defensive measures in advance.  Perhaps
someone (even I) may change "lint" to complain about such usage.

"Lint" is permitted, nay, encouraged to check for possible problems
that are nonetheless legal C usage.  It is almost always an error in
MY code for a function to be declared to return a value but to fail
to do so, just as it's almost always an error for MY code to not use
the value returned by a function.  This is a consequence of a coding
style that tries to be as type-correct as possible.  To the extent
that "lint" supports such a style, it can help find coding errors.

Actually all #ifdef lint stuff is ugly, and I would have removed it
before posting the code had I guessed that a discussion was imminent.