Solved

C expressions inherently Boolean?

Posted on 2004-10-19
7
792 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
Comment Utility
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
Comment Utility
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
Comment Utility
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
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 
LVL 9

Assisted Solution

by:ankuratvb
ankuratvb earned 20 total points
Comment Utility
0
 
LVL 45

Accepted Solution

by:
Kdo earned 370 total points
Comment Utility
>> 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
Comment Utility
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
Comment Utility
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

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

Suggested Solutions

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…
This is a short and sweet, but (hopefully) to the point article. There seems to be some fundamental misunderstanding about the function prototype for the "main" function in C and C++, more specifically what type this function should return. I see so…
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.
Video by: Grant
The goal of this video is to provide viewers with basic examples to understand and use while-loops in the C programming language.

771 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

10 Experts available now in Live!

Get 1:1 Help Now