Solved

C expressions inherently Boolean?

Posted on 2004-10-19
7
796 Views
Last Modified: 2010-04-15
I'm having trouble understanding something I've read.  It says that in C all expressions have a datatype and generate a value and  the value of any expression is inherently boolean being either zero/FALSE or non-zero/TRUE.  
Also, that function return values are inherently boolean unless specified otherwise.
Since it didn't give any concrete examples, I'm confused as to what that means...
how can look at an expression and determine the boolean value it generates?
0
Comment
Question by:day7
7 Comments
 
LVL 45

Expert Comment

by:Kdo
ID: 12354499
Hi day7,

Easy enough.  As you've already stated, "the value of any expression is inherently boolean being either zero/FALSE or non-zero/TRUE".


In a nutshell, that means that all non-zero values test positive for TRUE and negative for FALSE.  Zero values test positive for FALSE and negative for TRUE.

hmm.... After rereading that, I guess I didn't help...

Here are a couple of examples.


int Value;

 for (Value = -2; Value < 3; Value++)
   if (Value)
      print (" %d is TRUE\n", Value);
   else
      print (" %d is FALSE\n", Value);



C also lets you put boolean expressions "inline".  In the following statement intValue is set to 1 if SomeValue is non-zero, otherwise it is set to zero.

 intValue = (SomeValue) ? 1 : 0;


Taking this a step further, we'll rewrite the for() loop from above.

  for (Value = -2; Value < 3; Value++)
    printf (" %d is %s\n", Value, Value ? "TRUE" : "FALSE");

Notice if you will, how we've used the variable *Value* here in the for() statement, we set it, we test it for being less than 3, and we increment it.  In the print statement we also evaluate it based on it being "inherently boolean".


Something else to note.  C is a computer language and like any computer language it has a set of rules that define it.  These rules are called its "grammar".

The grammar for the C for() statement is roughly:

  for ((expression);(boolean expression);(expression))

It's very common for a for() statement to look like the one above.  Set a variable, test the same variable for an upper limit, and increment the variable.  But what if the limit is zero?

  for (Value = -10; Value; Value++)
    printf (" Value is %d\n", Value);

Here we've used the "inherently boolean" characteristic to test for the end of the loop.  As long as Value is non-zero the for() statement will continue looping.  We could have written it like this, too:

  for (Value = -10; Value < 0; Value++)

or even:

  for (Value = -10; Value != 0; Value++)

In this case, the will all behave exactly the same.



And that's a fairly long-winded explanation for how a Variable is both an integer and "inherently boolean".  C simply treats all non-zero values as TRUE and zero values as FALSE.

Good Luck!
Kent
0
 

Author Comment

by:day7
ID: 12354813
thanks so far!...
couple questions...
what you've explained is simple enough when we're dealing with integers, but since it says all expressions are inherently boolean how does it deal with other datatypes like char or float or even user defined types?  

 an extension to this question is does C specifically evaluate every expression for it's bool value  - and what criteria does it use to determine the bool value of non-int expressions  - and does the compiler store that info somehow or is it generate when it is requested at run time?

also from what I understand if for ex. I have a function that returns -1 when a condition is false the inherent boolean value of -1 is true so based on that I better be sure I don't use that as a test?
 
0
 
LVL 15

Assisted Solution

by:efn
efn earned 50 total points
ID: 12354924
Your source is incorrect in stating that the value of any expression is inherently boolean.  This is true only if the type of the expression is scalar.  Arithmetic types and pointer types are scalar.  There are also aggregate types, arrays and structures.  An expression can denote an object of an aggregate type, and in that case, it can't be evaluated as true or false.

Function return values are inherently boolean unless specified otherwise in that if the return type of a function is unspecified, it is int by default, and int is a scalar type, so it can be interpreted as boolean.

The truth value of any expression is evaluated by comparing it to zero, where zero means false and non-zero means true.  This applies to floating-point numbers and pointers as well as integral types.

If a compiler can evaluate an expression at compile time, it is likely to store the value and and not generate code to evaluate the expression at run time.

You are correct that you should not use built-in Boolean comparison with your function that returns -1 for false.  You will probably want to do something like

if (f() != -1)

rather than

if (f())

--efn
0
ScreenConnect 6.0 Free Trial

At ScreenConnect, partner feedback doesn't fall on deaf ears. We collected partner suggestions off of their virtual wish list and transformed them into one game-changing release: ScreenConnect 6.0. Explore all of the extras and enhancements for yourself!

 
LVL 9

Assisted Solution

by:ankuratvb
ankuratvb earned 20 total points
ID: 12355927
0
 
LVL 45

Accepted Solution

by:
Kdo earned 370 total points
ID: 12357093
>> how does it deal with other datatypes like char or float or even user defined types?  

Are you familiar with assembly language programming?  A good "general rule" is that any value that can be stored in a register falls into the category of inherently boolean.  The register is tested for non-zero/zero to detect true/false.  chars (which are really just 8-bit integers), shorts, ints, and longs all work this way "natively".  floating point values MAY be an issue with certain systems, depending on how they are implemented.  (integer zero may not be the same as floating point zero)

User defined types are an abstraction that aren't really a single data type.  structs and unions are combinations of types.  so they don't have a value that can be singly interpretted.


>> an extension to this question is does C specifically evaluate every expression for it's bool value  - and what criteria does it use to determine the bool value of non-int expressions  - and does the compiler store that info somehow or is it generate when it is requested at run time?

C does not "specifically evaluate every expression for it's bool value" unless the context in which the value is used requires a boolean value.

That is,  "A = B + C" is evaluated arithmetically because there is no need for a logical value.

However, "A = (D == E) ? B : C" is evaluated both logicallly and arithmetically because both concepts apply.

non-integers are a bit unique and their evaluation depends on the data type.  Pointers are pretty easy.  On most modern systems pointers are the same length as integers so evaluating them is easy.

if (SomePointer == NULL)

is equivalent to:

if (SomePointer == 0)

As I mentioned earlier, floating point MAY be uniquely handled on some systems, but the compiler will take care of that and a floating point zero will evaluate to false, just as if it were an integer zero.

If a value can be interpretted for zero, it is a run-time decision.  Always.


>> also from what I understand if for ex. I have a function that returns -1 when a condition is false the inherent boolean value of -1 is true so based on that I better be sure I don't use that as a test?

That's fine.  You can return any value that you want and use it any way that you want.  But if your return value is simply true/false, then returning 1/0 is more efficient.  And in the long run it will make more sense to you to do things a "standard' way.

But keep in mind that C kind of skates around these issues a bit for convenience.  Consider fopen().  When it is successful it returns a pointer to a stream otherwise it returns NULL.  (true/false)  Now consider the lower-level routine open().  When it is successful it returns the integer file handle.  File handles are defined as being non-negative integers so returning zero means that the function actually worked.  When open() fails, it returns -1.



Kent
0
 
LVL 22

Assisted Solution

by:grg99
grg99 earned 30 total points
ID: 12358495
C is rather loose with "boolean" quantities.   One way of looking at it is: expressions have a result type, which is only truly boolean (0 or 1) if the last operation was a comparison or logical operation.

All other operatins result in a scalar result.  If you use that result in a boolean context, such as: "if( expression ), then the compiler generates code to test the expression against zero.
0
 
LVL 2

Assisted Solution

by:Peter-Darton
Peter-Darton earned 30 total points
ID: 12503325
In old-style C (aka K&R C), a function is assumed to return an int unless specified otherwise, and an int (as folks have stated above) is the nearest thing to a boolean than C has, so in that respect, a function does return a boolean value because it returns a value that can be used as a boolean.

I don't think I'd explain it quite like that tho' - a function is implicitly assumed to return an int
 - stating it returns a boolean is a bit misleading as anything a function is capable of returning can be used as a boolean.

In ANSI-C, you'll get lots of warnings (or even errors) if you don't declare a function before you try to use it, but the compiler will assume it's an int unless told otherwise.

So if you've got a program which goes

#include <stdio.h>
main(argc, argv)
  int argc;
  char **argv;
{
  int answer = fred();
  printf("Fred returned %d\n", answer );
}

int fred()
{
  return 42;
}

It'd compile and work using K&R C, and print "Fred returned 42".

If we had instead
  float answer = fred();
  printf("Fred returned %f\n", answer );
and
float fred()
{
  return 42.0;
}
then it'd all go horribly wrong as fred would be assumed to return an int, so "answer" would be the result of taking 42.0 as a float, then interpreting that binary data as an int (hint: it won't be 42), then converting that number into a float and printing it.
This is why we don't use K&R C anymore (unless forced to!)

In ANSI-C you'd get a lot of errors, as K&R used different argument declarations.
In ANSI-C, you'd have to do

#include <stdio.h>

int fred(void);
main(int argc, char **argv)
{
  int answer = fred();
  printf("Fred returned %d\n", answer );
}

int fred()
{
  return 42;
}


If we were to do the same "float" stuff as above, we would have to change our declaration of "int fred(void);" to "float fred(void);" otherwise the compiler would complain we promised it a fred that returned an int and then defined one that returned a float.
(This is why we prefer ANSI-C to K&R-C)

I would hope that nobody is using old K&R compilers anymore (last time I used one was in the early 1990s) - the lack of function return type checking was bad, but the lack of function argument checking was worse.  Not a good language to learn.

Stick with ANSI-C or C++ and it'll get stroppy if you don't tell it what a function returns and what arguments a function takes, that way there will be no "implict" stuff & no assumptions.
Assumptions are dangerous.
0

Featured Post

U.S. Department of Agriculture and Acronis Access

With the new era of mobile computing, smartphones and tablets, wireless communications and cloud services, the USDA sought to take advantage of a mobilized workforce and the blurring lines between personal and corporate computing resources.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Summary: This tutorial covers some basics of pointer, pointer arithmetic and function pointer. What is a pointer: A pointer is a variable which holds an address. This address might be address of another variable/address of devices/address of fu…
Windows programmers of the C/C++ variety, how many of you realise that since Window 9x Microsoft has been lying to you about what constitutes Unicode (http://en.wikipedia.org/wiki/Unicode)? They will have you believe that Unicode requires you to use…
The goal of this video is to provide viewers with basic examples to understand and use structures in the C programming language.
Video by: Grant
The goal of this video is to provide viewers with basic examples to understand and use for-loops in the C programming language.

863 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

19 Experts available now in Live!

Get 1:1 Help Now