[comp.lang.c] Constants in conditionals

torek@elf.ee.lbl.gov (Chris Torek) (02/19/91)

>In article <9890@dog.ee.lbl.gov> I wrote:
>>... these are effectively the same as `if (0)', hence a good compiler
>>should warn about a constant in conditional context [...]

In article <1991Feb18.113919.28217@watmath.waterloo.edu>
datangua@watmath.waterloo.edu (David Tanguay) writes:
>Oooo I hope not! I occasionally use constants in ifs.
>"if( PATCH_MODE ) { ... }", where PATCH_MODE is a cpp macro (0 or 1).

Well, a *really* good compiler will allow you to say `yes, I know
this is a constant, but I want to test it anyway'.

(This is one possible use for an ANSI `#pragma'.)
-- 
In-Real-Life: Chris Torek, Lawrence Berkeley Lab EE div (+1 415 486 5427)
Berkeley, CA		Domain:	torek@ee.lbl.gov

robert@isgtec.uucp (Robert Osborne) (02/20/91)

datangua@watmath.waterloo.edu (David Tanguay) writes:
> In article <9890@dog.ee.lbl.gov> torek@elf.ee.lbl.gov (Chris Torek) writes:
> >Both of these are effectively the same as `if (0)', hence a good compiler
> >should warn about a constant in conditional context [...]
> 
> Oooo I hope not! I occasionally use constants in ifs.
Oooo I hope SO!  I occasionally use constants in ifs...
usually by mistake!   Since it is sort of a stupid thing
to do (why use an "if" when you already know which way you are
going to branch?) I would hope that it would produce a warning.

> "if( PATCH_MODE ) { ... }", where PATCH_MODE is a cpp macro (0 or 1).
> I know I coud use #if (or #ifdef), but I find them too ugly.
Nice attitude towards programming;
"I don't use any language constructs *I* don't find aesthetically pleasing"
I know that any compile dependency, whether for architecture, Unix type,
or to exclude some feature (ie. debugging), will have an
#if something
#endif
associated with it.
(Well, I at least at ISG I know this; now it seems this doesn't
extend to the whole world :-(
> I could also  use an external, but then I don't get
> the dead code elimination.
Oh now I see,  you left the smilee off your article.

Rob.
--
Robert A. Osborne   ...uunet!utai!lsuc!isgtec!robert or robert@isgtec.uucp

scs@adam.mit.edu (Steve Summit) (02/20/91)

In article <10032@dog.ee.lbl.gov> torek@elf.ee.lbl.gov (Chris Torek) writes:
>>In article <9890@dog.ee.lbl.gov> I wrote:
>>>... these are effectively the same as `if (0)', hence a good compiler
>>>should warn about a constant in conditional context [...]
>
>Well, a *really* good compiler will allow you to say `yes, I know
>this is a constant, but I want to test it anyway'.
>
>(This is one possible use for an ANSI `#pragma'.)

Actually, if I were writing lint, I'd have it complain by default
about "constant in conditional context" only for compile-time
constant (nontrivial) expressions, not compile-time constant
CONSTANTS.

The "constant in conditional context" message is merely one
weapon in our arsenal against that all-time most common C bug:

	if(i = 0)

(I still get bit by this from time to time, whether from sticky
keyboards or sticky fingers I'm not sure.)  However,
constructions like

	while(TRUE)

are so common that it seems better not to warn about them.
(A useful distinction between if(constant) and while(constant)
could probably be made, since intentional usages of if(constant)
are quite a bit less common.  Chris is right; the best
compilers/lints would give you fine control over this stuff, if
they're into quality warning messages.)

                                            Steve Summit
                                            scs@adam.mit.edu

dave@cs.arizona.edu (Dave P. Schaumann) (02/20/91)

In article <1991Feb20.034136.14554@athena.mit.edu> scs@adam.mit.edu writes:
>[...]
>The "constant in conditional context" message is merely one
>weapon in our arsenal against that all-time most common C bug:
>
>	if(i = 0)
>
>(I still get bit by this from time to time, whether from sticky
>keyboards or sticky fingers I'm not sure.)  However,
>constructions like
>
>	while(TRUE)
>
>are so common that it seems better not to warn about them.

Actually, I had some interesting ideas about this when I was taking a compiler
writing course a year ago.  We could have several types (internally, of course)
for "integer" expressions:  definitiely_bool, possibly_bool, unlikely_bool.
Operators like <, ==, >, &&, || would yeild types "definitely_bool".  Simple
integer values could be "possibly_bool", and other operators (especially =)
would have type "unlikely_bool".  That way, the expression in while(TRUE) would
have type "possibly_bool", and if(i = 0) would have type "unlikely_bool".

A lint implementation or aggressive compiler could then flag expressions having
type "unlikely_bool" expressions occurring in a boolean context.

-- 
Dave Schaumann      | Is this question undecidable?
dave@cs.arizona.edu |

jef@well.sf.ca.us (Jef Poskanzer) (02/21/91)

In the referenced message, pt@geovision.gvc.com wrote:
}Sorry, but #ifdef or #if is SOOO basic, that if you don't know how to use
}it (or refuse to for wierd reasons), you loose.

Using "if" for conditional compilation instead of "#if" has one major
advantage: the outshipped code continues to get checked for syntax
errors.  For machine-dependent code you probably don't want this,
otherwise you probably do.  But you're right, you do have to check
the generated assembly code to make sure your compiler is doing
the right thing.  These days, most do.
---
Jef

  Jef Poskanzer  jef@well.sf.ca.us  {apple, ucbvax, hplabs}!well!jef
"It's what you learn after you know it all that counts." -- John Wooden

datangua@watmath.waterloo.edu (David Tanguay) (02/21/91)

In article <858@isgtec.UUCP> robert@isgtec.UUCP (Robert Osborne) writes:
|datangua@watmath.waterloo.edu (David Tanguay) writes:
|> "if( PATCH_MODE ) { ... }", where PATCH_MODE is a cpp macro (0 or 1).
|> I know I coud use #if (or #ifdef), but I find them too ugly.
|Nice attitude towards programming;
|"I don't use any language constructs *I* don't find aesthetically pleasing"

Same one you're advocating: if( constant ) is a valid language construct
that you don't want anybody to use (i.e., you want the compile to warn
people off of it).

|I know that any compile dependency, whether for architecture, Unix type,
|or to exclude some feature (ie. debugging), will have an
|#if something
|#endif
|associated with it.

I still use ifdefs for these kinds of things (I want non-portable code to
stand out). The constants in ifs appear where one piece of source is
used for different programs (e.g., C code parser vs. lint). I'm currently
using it in a debugger to select between a debugger program, an
executable file editor, and a post mortem analyser.

|> I could also  use an external, but then I don't get
|> the dead code elimination.
|Oh now I see,  you left the smilee off your article.

No. On the architectures I have to work on, I need all the memory I can
get. Any functions that are called from dead code will not get linked
in, but if I switch on an external, they will.

Paul Tomblin writes:
| Sorry, but #ifdef or #if is SOOO basic, that if you don't know how to use
| it (or refuse to for wierd reasons), you loose.

Another case I've used is if( sizeof(int) < sizeof(long) ).
My constants are generally cpp macros created in an #ifdef in a
header somewhere. It's an aesthetic argument. Do you also not hire
programmers who use the wrong brace style?

Chris Torek writes:
| Well, a *really* good compiler will allow you to say `yes, I know
| this is a constant, but I want to test it anyway'.
| (This is one possible use for an ANSI `#pragma'.)

A command line switch is fine, but a #pragma sort of defeats the purpose
(unless you mean just one with file scope).
-- 
David Tanguay        datanguay@watmath.waterloo.edu        Thinkage, Inc.

pt@geovision.gvc.com (Paul Tomblin) (02/21/91)

scs@adam.mit.edu (Steve Summit) writes:
>(I still get bit by this from time to time, whether from sticky
>keyboards or sticky fingers I'm not sure.)  However,
>constructions like

>   while(TRUE)

>are so common that it seems better not to warn about them.

Simple solution:

Replace:

    while (TRUE)
    {
        ...
    }

with:

considered_harmful:
    ...
    goto considered_harmful;

:-) :-)
-- 
Paul Tomblin, Department of Redundancy Department.       ! My employer does 
The Romanian Orphans Support Group needs your help,      ! not stand by my
Ask me for details.                                      ! opinions.... 
pt@geovision.gvc.com or {cognos,uunet}!geovision!pt      ! Me neither.

pt@geovision.gvc.com (Paul Tomblin) (02/23/91)

jef@well.sf.ca.us (Jef Poskanzer) writes:

>In the referenced message, pt@geovision.gvc.com wrote:
>}Sorry, but #ifdef or #if is SOOO basic, that if you don't know how to use
>}it (or refuse to for wierd reasons), you loose.

>Using "if" for conditional compilation instead of "#if" has one major
>advantage: the outshipped code continues to get checked for syntax
>errors.  For machine-dependent code you probably don't want this,
>otherwise you probably do.  But you're right, you do have to check
>the generated assembly code to make sure your compiler is doing
>the right thing.  These days, most do.

I think you'd be making a mistake in assuming that because code still
compiles without error that it is still correct.  "If it's not exercised,
it's not correct" is a good assumption that any future maintainer of the code
would have to make.  Code around here that is "#if 0"ed out, is usually
expunged the next time a bug shows up it that area of code.  If it's 
"if (FALSE)"ed out, it will be expunged the first time it's spotted. 
(And the coder will get a talking to!  PCC doesn't do the right thing.)

We use #ifdef for two reasons: Machine dependant code, and debugging. 
When trying out new things, or temporarily removing something to try
another approach, we tend to put in #ifdefs, but we try and remove them
when we are done.  Anything else is asking for maintainence headaches.
(I know, I'm in charge of maintainence!)
-- 
Paul Tomblin, Department of Redundancy Department.       ! My employer does 
The Romanian Orphans Support Group needs your help,      ! not stand by my
Ask me for details.                                      ! opinions.... 
pt@geovision.gvc.com or {cognos,uunet}!geovision!pt      ! Me neither.

robert@isgtec.UUCP (Robert Osborne) (02/28/91)

In article <1991Feb21.121452.29969@watmath.waterloo.edu>,
datangua@watmath.waterloo.edu (David Tanguay) writes:
#In article <858@isgtec.UUCP> robert@isgtec.UUCP (Robert Osborne) writes:
#|datangua@watmath.waterloo.edu (David Tanguay) writes:
#|> "if( PATCH_MODE ) { ... }", where PATCH_MODE is a cpp macro (0 or 1).
#|> I know I coud use #if (or #ifdef), but I find them too ugly.
#|Nice attitude towards programming;
#|"I don't use any language constructs *I* don't find aesthetically pleasing"
#
#Same one you're advocating: if( constant ) is a valid language construct
#that you don't want anybody to use (i.e., you want the compile to warn
#people off of it).
No, not the same at all.  I want a warning because, like most people, when
I have a constant in a conditional it is usually a mistake.  If it isn't
then I ignore the warning.  Note that
	i = 0;
	start_loop:
		if( i >= 10 ) goto end_loop;
		...
		i++;
	goto start_loop;
	end_loop:
is a "valid language construct" but most people use
	for(i=0; i<10;i++) {
		...
	}

Rob.
----
Robert A. Osborne   ...uunet!utai!lsuc!isgtec!robert or robert@isgtec.uucp