TRUE/FALSE values: Point / Counterpoint

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • donbock
    Recognized Expert Top Contributor
    • Mar 2008
    • 2427

    TRUE/FALSE values: Point / Counterpoint

    A side-discussion developed in the Wierd Visual Studio Problem thread. Rather than continue to hijack that topic, I've created a new thread and copied over the relevant postings.
    Originally posted by Andr3w
    <text of reply snipped -- it was the following code that triggered the side-discussion>
    Code:
    //////////////////////////////////////////////////////////////////////////
    //																		//
    // Parent Project Name: sample project for bytes
    //																		//
    // Project file: boom.cpp							//
    // 																		//
    // Description: Demonstrate offset needed in allocaton					//
    //																		//
    //																		//
    // Notes:	-															//															
    //																		//	
    // Date Edited: 2009/03/20												//
    // Version:	1.0r														//
    //																		//
    // Coder: Andrew Grammenos (andreas.grammenos@gmail.com)				//
    //																		//
    // License:	BSD License													//									
    //																		//
    //////////////////////////////////////////////////////////////////////////
    
    #include <stdlib.h>
    #include <string.h>
    #include <malloc.h>
    
    // set the codes
    #define		ERROR_CODE 1
    #define		ALLOCATION_LIMIT -1
    
    // disable this in nix and legacy versions of VS
    #pragma warning ( disable : 4996 )
    
    // set true false macros
    #define TRUE 0;
    #define FALSE 1;
    
    // forward function declarations
    
    int createTable();
    
    void freeChunks( char **ptr, int tabSize );
    
    int addStringsToTable(char **ptr);
    
    int main(int argc, char* argv[])
    {
    	createTable();
    
    	return TRUE;
    }
    
    
    int createTable()
    {
    	// example size
    	int tabSize = 5;
    
    	// now that we have our choice, let's create our dynamic string pointer
    	// array using the specified size
    	char **sptrTable = (char**)calloc( (tabSize+1), sizeof(int) );
    
    	// check for valid allocation
    	if( sptrTable == NULL )
    	{
    		fprintf( stdout,"\nNo memory was allocated due to insufficient memory, please free up some memory and try again\nThe program will now exit\n");
    		return ERROR_CODE;
    	}
    
    	// set our exit code for the allocation size
    	sptrTable[tabSize] = (char*)calloc( 1, sizeof(int) );
    	sptrTable[tabSize][0] = ALLOCATION_LIMIT;
    
    
    	// pass the address of the pointer table to our function
    	// that adds the strings
    	addStringsToTable( sptrTable );
    
    
    	// free up what we used
    	freeChunks(sptrTable, tabSize);
    
    	return TRUE;
    
    }
    
    void freeChunks( char **ptr, int tabSize )
    {
    
    	int index = 0;
    
    	// free the columns
    	while( index <= tabSize && (ptr[index] != NULL) )
    	{
    		free( ptr[index] );
    		index++;
    	}
    
    	// free the rows
    	free( ptr );
    }
    
    int addStringsToTable(char **ptr)
    {
    
    	// create  a buffer to store the string that the user will input
    	char buff[BUFSIZ];
    	char inB = 0;
    
    	int allocCheck = FALSE;
    
    	int index = 0;
    
    	while ( allocCheck )
    	{
    		// prompt the user for input
    		fprintf(stdout, "\nPlease enter a string (max length is: %d)", BUFSIZ);
    
    		// get the input
    		fscanf( stdin, "%s", &(buff) );
    
    		// create the string in the table and
    		// check if the memory was allocated ok
    		if ( (ptr[index] = (char *)calloc( strlen(buff) /* + 1 uncomment to run fine ;) */, sizeof(char) ) ) == NULL )
    		{
    			return ERROR_CODE;
    		}
    
    		// copy the actual string
    		strcpy( ptr[index], buff );
    
    		// print diagnostic message
    		fprintf(stdout, "\nString successfully inserted\nPlease type any key to continue or E to terminate and press enter\n\n");
    
    		// advance the pointer to next value
    		ptr[index++];
    
    		// check for allocation limit
    		if ( ptr[index] != NULL && ptr[index][0] == (ALLOCATION_LIMIT) )
    		{
    			fprintf(stdout, "\n\nLimit reached exiting now");
    			allocCheck = TRUE;
    		}
    	}
    	return TRUE;
    }
  • donbock
    Recognized Expert Top Contributor
    • Mar 2008
    • 2427

    #2
    Originally posted by donbock
    Code:
    // set true false macros
    #define TRUE 0;
    #define FALSE 1;
    Originally posted by donbock
    It is virtually universal practice to use a nonzero value for true (typically "1") and "0" for false. Was this a typo or did you intend to do it this way? Statements like if(TRUE){...} or while(FALSE){.. .} will do the exact opposite of what you expect. The hangs you're experiencing might be caused by inadvertently infinite loops.
    ............... .....

    Comment

    • donbock
      Recognized Expert Top Contributor
      • Mar 2008
      • 2427

      #3
      Originally posted by Andr3w
      Well, in unix systems true is supposed to be 0 (if a thread is successful it returns 0) and most main function do so. Also most ANSI C functions return 0 when they succeed and a non-zero value if they don't or want to indicate a status (like strlen) Please try to compile the program and see what I am saying by uncommenting the +1 offset that I have in line 122.

      Now for the pragma in newer versions of visual studio microsoft has new more "secure" function to replace the legacy printf, fprintf and so on using printf_s, fprintf_s etc, if you don't disable that is nugs you with a warning during compile time in newer versions which is annoying and I tend to disable it all the time :P

      We chat so much while the original user hasn't responded yet!! kewl!! ^_* haha
      ............... .....

      Comment

      • donbock
        Recognized Expert Top Contributor
        • Mar 2008
        • 2427

        #4
        Originally posted by donbock
        I would be happier if you used the terms SUCCESS and FAILURE rather than TRUE and FALSE. The C Standard is clear and unambiguous: an integer value of zero means false and any nonzero value means true.
        ............... .....

        Comment

        • donbock
          Recognized Expert Top Contributor
          • Mar 2008
          • 2427

          #5
          Originally posted by Andr3w
          Well, in any case whatever differences we have in our coding style in this post we are not here to debate on how we write code :P at least I think that...
          ............... .....

          Comment

          • donbock
            Recognized Expert Top Contributor
            • Mar 2008
            • 2427

            #6
            I don't think this is an issue of coding style. Consider the following code:
            Code:
            #define TRUE 0
            #define FALSE 1
            
            int isDone;
            ...
            if (isDone) {
               <something that only happens when you're done>
            }
            If you set isDone to TRUE then the conditional code doesn't execute; if you set isDone to FALSE then the conditional code executes. This is counterintuitiv e behavior. You get similar unexpected behavior if you use isDone as the condition to terminate a loop.

            C99 added <stdbool.h> as a new standard header. This header is required to contain something equivalent to:
            Code:
            #define true 1
            #define false 0
            The chances of confusion and error abound when "true" means the same thing as "FALSE".

            Comment

            • Andr3w
              New Member
              • Nov 2007
              • 42

              #7
              Well, I am careful with my code in order to get it working and bug free. I have a coding style and you have yours. It's a matter of preference and I know this behavior is present if I set the values that way...

              Anyway really I don't think there is a point continuing this really as there is no argument to begin with, or at least I think so

              Comment

              • JosAH
                Recognized Expert MVP
                • Mar 2007
                • 11453

                #8
                Originally posted by donbock
                Code:
                // set true false macros 
                #define TRUE 0; 
                #define FALSE 1;
                That makes -2 points (-1 for each semicolon). Next!

                kind regards,

                Jos

                Comment

                • Andr3w
                  New Member
                  • Nov 2007
                  • 42

                  #9
                  weeee thanks for pointing it out...stupid typos are a common mistake...for all programmers...

                  Anyway I'll be more careful next time...to avoid typos

                  be safe

                  Comment

                  • JosAH
                    Recognized Expert MVP
                    • Mar 2007
                    • 11453

                    #10
                    Originally posted by Andr3w
                    weeee thanks for pointing it out...stupid typos are a common mistake...for all programmers...

                    Anyway I'll be more careful next time...to avoid typos
                    Also better turn those definitions around, as in:

                    Code:
                    #define TRUE 1
                    #define FALSE 0
                    I, for one, rely on the fact that TRUE is a non-zero value and 1 to be exact; I like to use that value in arithmetic expressions when appropriate. Also I expect a true expression to succeed in a conditional expression. Even more I want the following to succeed as well:

                    Code:
                    if ((1+1 == 2) == TRUE) { ... }
                    kind regards,

                    Jos

                    Comment

                    • weaknessforcats
                      Recognized Expert Expert
                      • Mar 2007
                      • 9214

                      #11
                      Defining TRUE = 1 and FALSE = 0 won't work. Never has worked. Remember that 25 is also TRUE.

                      You need to do it this way:
                      Code:
                      #define FALSE  0
                      #deifne TRUE  !FALSE

                      Comment

                      • JosAH
                        Recognized Expert MVP
                        • Mar 2007
                        • 11453

                        #12
                        Originally posted by weaknessforcats
                        Defining TRUE = 1 and FALSE = 0 won't work. Never has worked. Remember that 25 is also TRUE.
                        True (sic) but the canonic integer value for 'true' equals 1. Read the Standard (e.g. for the ! operator):

                        Originally posted by C Standard
                        The result of the logical negation operator ! is 0 if the value of
                        its operand compares unequal to 0, 1 if the value of its operand
                        compares equal to 0. The result has type int . The expression !E is
                        equivalent to (0==E) .
                        Here's another (more realistic) example:

                        Code:
                        #define SIGN(x) (((x) > 0) - ((x) < 0))
                        I can use that integer value in integer expressions if I want to so I expect any symbolic value TRUE to equal 1.

                        kind regards,

                        Jos

                        Comment

                        • weaknessforcats
                          Recognized Expert Expert
                          • Mar 2007
                          • 9214

                          #13
                          I have no idea about canonical or not but this doesn't work as expected:

                          Code:
                          #define TRUE 1
                          #define FALSE 0
                          
                          int data = 25;
                          if (data == TRUE)
                          {
                                  printf("It's true\n");
                          }
                          TRUE has to be !FALSE

                          Comment

                          • JosAH
                            Recognized Expert MVP
                            • Mar 2007
                            • 11453

                            #14
                            Originally posted by weaknessforcats
                            I have no idea about canonical or not but this doesn't work as expected:

                            Code:
                            #define TRUE 1
                            #define FALSE 0
                            
                            int data = 25;
                            if (data == TRUE)
                            {
                                    printf("It's true\n");
                            }
                            TRUE has to be !FALSE
                            Then it still doesn't work; you are mixing up the (conceptual) boolean domain with the integer domain. btw !FALSE will be equal to 1.

                            kind regards,

                            Jos

                            Comment

                            • donbock
                              Recognized Expert Top Contributor
                              • Mar 2008
                              • 2427

                              #15
                              I'm pretty sure that the Standards all guarantee that any logical expression will evaluate to precisely "0" or "1" so JosAH's SIGN macro is portable and safe.

                              On the other hand, conditional instructions (if, for, while) consider all nonzero argument values to be equivalent. I'm paranoid that a boolean variable might somehow be assigned a nonzero value other than "1". If that were to happen then explicit comparisons to canonical TRUE and FALSE values would see a value that was neither true nor false, possibly resulting in some weird inconsistent path through a series of conditionals.

                              I don't allow my team to perform comparisons to a canonical TRUE value. I have them either treat boolean variables as predicates or perform all comparisons against the canonical FALSE value.
                              Code:
                              void func1(int isThatCondition) {
                                 if (isThatCondition) {...}
                              }
                              
                              void func2(int isThatCondition) {
                                 if (isThatCondition != FALSE) {...}
                              }
                              My preference is to use booleans as predicates, being careful that the variable names include an appropriate existence verb.

                              Comment

                              Working...