[comp.sys.ibm.pc] Spurious Turbo-C warning -- how do I get around it?

dougs@videovax.tv.Tek.com (Doug Stevens) (09/14/89)

I'm trying to figure out how to get around a 'feature' of Turbo-C. 
I like to run makes with all the warnings and errors on, but when I
compile a module with this type of structure (vastly simplified to
show the point):
	
	#define TRUE	1
	int test(void)
	{
		while (TRUE) {
			return(1);
		}
	}

I get this warning:

	tcc -w -S test.c
	Warning test.c 8: Function should return a value in function test

even though the module DOES always return a value.
I can get around it by adding a dummy return statement after the loop:

	#define TRUE	1
	int test(void)
	{
		while (TRUE) {
			return(1);
		}
		return(1);
	}

But then, this SHOULD generate a warning about unreachable code. It also
wastes code space.

Anyone figured out a way around this?

toma@tekgvs.LABS.TEK.COM (Tom Almy) (09/15/89)

In article <5554@videovax.tv.Tek.com> dougs@videovax.tv.Tek.com (Doug Stevens) writes:
>I'm trying to figure out how to get around a 'feature' of Turbo-C. 
>I like to run makes with all the warnings and errors on, but when I
>compile a module with this type of structure (vastly simplified to
>show the point):
	
>	#define TRUE	1
>	int test(void)
>	{
>		while (TRUE) {
>			return(1);
>		}
>	}

>I get this warning:

>	tcc -w -S test.c
>	Warning test.c 8: Function should return a value in function test

I tried it and got no warning.  Are you using Turbo-C 2.0?  But I have seen
this error with other compilers (in particular, Metaware High-C).

>I can get around it by adding a dummy return statement after the loop:
[...]
>			return(1);
>		}
>		return(1);
>	}

>But then, this SHOULD generate a warning about unreachable code. It also
>wastes code space.

A check shows no unreachable code message.  Yet no code was generated for
the return.

>Anyone figured out a way around this?

Well, this will work:

	#define TRUE	1
	int test(void)
	{
		while (TRUE) {
			break;
		}
	return(1);
	}

Tom Almy
toma@tekgvs.labs.tek.com
Standard Disclaimers Apply

Devin_E_Ben-Hur@cup.portal.com (09/18/89)

> I'm trying to figure out how to get around a 'feature' of Turbo-C.
> I like to run makes with all the warnings and errors on, but when I
> compile a module with this type of structure (vastly simplified to
> show the point):
> 
>         #define TRUE    1
>         int test(void)
>         {
>                 while (TRUE) {
>                         return(1);
>                 }
>         }
> 
> I get this warning: [warning about no return value for function]
> 
> Anyone figured out a way around this?

Sure try:

         #define TRUE    1
         int test(void)
         {
                 while (TRUE) {
                       break; /* or goto done; */
                 }
         /* done: */
                 return(1);
         }

or add
#pragma warn -rvl /* before the function end */
and
#pragma warn .rvl /* after the function end */


Devin_Ben-Hur@Cup.Portal.Com
...ucbvax!sun!portal!cup.portal.com!devin_ben-hur

tom@stiatl.UUCP (Tom Wiencko) (09/18/89)

In article <5554@videovax.tv.Tek.com> dougs@videovax.tv.Tek.com (Doug Stevens) writes:
>>I'm trying to figure out how to get around a 'feature' of Turbo-C. 
>>	
>>	#define TRUE	1
>>	int test(void)
>>	{
>>		while (TRUE) {
>>			return(1);
>>		}
>>	}
>> ...
>>
>>Anyone figured out a way around this?

Sure... don't return out of the middle of a loop.  

A properly structured subroutine has ONE entry point and ONE exit point, and
the entry point is at the beginning, and the exit point is at the end.
The proper (structured) way to write this routine is:

#define TRUE 1
int test(void)
{
	while (TRUE) {
		break;
	}
	return (1);
}

or even better (to use the C idiom properly):

int test(void)
{
	for (;;) {
		break;
	}
	return (1);
}

In general, warnings like this are there to tell you that you are writing
code which is not well structured, or is not properly taking advantage
of the appropriate C idioms.

Tom



-- 
Tom Wiencko                                            (w) (404) 977-4515
gatech!stiatl!tom                                  Wiencko & Associates, Inc.

desnoyer@apple.com (Peter Desnoyers) (09/19/89)

In article <6913@stiatl.UUCP> tom@stiatl.UUCP (Tom Wiencko) writes:
> In article <5554@videovax.tv.Tek.com> dougs@videovax.tv.Tek.com (Doug 
Stevens) writes:
> >>I'm trying to figure out how to get around a 'feature' of Turbo-C. 
> >>      #define TRUE    1
> >>      int test(void)
> >>      {
> >>              while (TRUE) {
> >>                      return(1);
> >>              }
> >>      }
> >> ...
  [error msg. is "function does not return a value"]
> >>Anyone figured out a way around this?

For years people have been writing things like:
  foo{
    while (1) return (0);
    return (0); /* to please lint */}

The problem is that lint (or Turbo C - or any computable program) can't 
figure out that you never drop through the bottom of the loop. This is 
best dealt with by putting in a return statement that will never be 
executed.

> Sure... don't return out of the middle of a loop.  
> A properly structured subroutine has ONE entry point and ONE exit point

I would not expect such dogma from someone programming in a heathen 
language such as C. In realistic usage it is often much cleaner, easier to 
read, and easier to maintain if multiple exit points are used. For 
instance, if an error early in a routine requires an exit after a 
different clean-up sequence than at the end of the routine, your code is 
going to be a lot cleaner if you use two return statements.

> In general, warnings like this are there to tell you that you are writing
> code which is not well structured, or is not properly taking advantage
> of the appropriate C idioms.

Single return per function is definitely NOT a C idiom. Always returning a 
value from a function declared to return a value is not just C idiom, but 
good (almost necessary) programming practice in any language. Having to 
put in spurious return statements due to the inability of lint (or 
lint-equivalent) programs to compute the halting problem is also a C 
idiom, for better or worse.

                                      Peter Desnoyers
                                      Apple ATG
                                      (408) 974-4469

tom@stiatl.UUCP (Tom Wiencko) (09/24/89)

In article <4216@internal.Apple.COM> desnoyer@apple.com (Peter Desnoyers) writes:
>>
>>I would not expect such dogma from someone programming in a heathen 
>>language such as C. In realistic usage it is often much cleaner, easier to 
>>read, and easier to maintain if multiple exit points are used. For 
>>instance, if an error early in a routine requires an exit after a 
>>different clean-up sequence than at the end of the routine, your code is 
>>going to be a lot cleaner if you use two return statements.

I maintain my original position: that such code (in C or any other
"heathen" language you may wish to discuss) is not well structured and
could use a dose of proper design.  The language is far less important
than the design principles used to structure it.

It has always been one of my pet peeves that people who program in C
believe that they can get away with lousy code simply because they are
programming in a language which lets them do it.  This is why I have been
a strong believer in using languages which better enforce structure
requirements (Pascal, Modula-2) for application code, and leave C for
systems and tools and places where it is necessary to break the rules.

>>
>>> In general, warnings like this are there to tell you that you are writing
>>> code which is not well structured, or is not properly taking advantage
>>> of the appropriate C idioms.
>>
>>Single return per function is definitely NOT a C idiom. Always returning a 
>>value from a function declared to return a value is not just C idiom, but 

The idiom I was speaking of was the "for (;;)" instead of the 
"while (TRUE)" construction.  Where you place the return is a structure issue, 
not an idiom issue.

Tom

-- 
Tom Wiencko                                            (w) (404) 977-4515
gatech!stiatl!tom                                  Wiencko & Associates, Inc.

dougs@videovax.tv.Tek.com (Doug Stevens) (09/26/89)

As the author of the original query, I think this discussion has generated
more heat than light. My original point was how to suppress a spurious
warning, the point being that I was trying to achieve an error-free,
warning-free compilation.

My contribution to the 'heat' regarding programming style: 
most of the suggestions I've received about 'improving' the style have
their own style drawbacks. Many suggested using 

	break;

to exit the loop; I have always regarded 'break' as a very thinly disguised
'goto'. If you're a fan of Duykstra's (spelling?), you avoid everything 
but while() and if() statements; even for(;;) is frowned upon, because
it is easily reduced to while().

Some situations seem to screw up even the best intentions toward good style 
(eg, error handling at the lowest level of communication or file-handling 
calls). I get caught up in style considerations to this extent:

	(1) Can someone who is new to the code understand and successfully
	modify it on the first viewing? Are the modules small enough to
	grasp? Do the names make sense? Are there side effects buried in
	conditional statements? Etc, etc, etc.

	(2) Can you prove (to an unbiased observer) that the code works?
	(No, I don't mean formal proof; I mean will any reasonable
	professional accept the argument).

I would suggest to anyone interested in improving programming style to
read 'Elements of Programming Style' (by Kernighan and Ritchie, I believe.
If you want to see what inspired them, read 'Elements of Style' by
Shrunk and White).

Sorry this is so long.

tom@stiatl.UUCP (Tom Wiencko) (09/27/89)

In article <5559@videovax.tv.Tek.com> dougs@videovax.tv.Tek.com (Doug Stevens) writes:
>
>I would suggest to anyone interested in improving programming style to
>read 'Elements of Programming Style' (by Kernighan and Ritchie, I believe.
>If you want to see what inspired them, read 'Elements of Style' by
>Shrunk and White).
>


Absolutely the most sensible thing I have read in this thread so far.



Tom


-- 
Tom Wiencko                                            (w) (404) 977-4515
gatech!stiatl!tom                                  Wiencko & Associates, Inc.