Thread: accessing structure members that are boolean pointers.

  1. #1
    Registered User
    Join Date
    Dec 2012
    Posts
    3

    accessing structure members that are boolean pointers.

    I'm having trouble accessing and printing a Boolean in the following:
    Code:
    #include <stdio.h>
    #include <stdbool.h>
    
    typedef struct 
    {
      char *name;
      bool *pboolean;
    } mystruct;
    
    int main (int argc, char *argv[])
    {
       mystruct data;
       mystruct *ptr_mystruct;
       ptr_mystruct = &data;
    
       ptr_mystruct->name = "me";
       printf("The name is: %s\n", ptr_mystruct->name);
       return 0;
    }
    This works fine for printing the name member but how do I do the same for the Boolean member?

  2. #2
    Ultraviolence Connoisseur
    Join Date
    Mar 2004
    Posts
    555
    Well according to man stdbool.h on my system:
    Code:
           The <stdbool.h> header shall define the following macros:
    
           bool   Expands to _Bool.
    
           true   Expands to the integer constant 1.
    
           false  Expands to the integer constant 0.
    
           __bool_true_false_are_defined
    
                  Expands to the integer constant 1.
    So you would print it with printf("%d", boolvalue) but more interesting and most likely useful way to print the value would probably be something like this:
    Code:
    printf("bool: %s\n", (boolval == true ? "True" : "False"));

  3. #3
    Registered User
    Join Date
    Dec 2012
    Posts
    3
    std10093, what I have already works for name. Your solution gives me an error:
    error: expected identifier before ‘(’ token
    I'm on Ubuntu Linux, gcc 4.5.2

    I should have been more clear. I don't want to print the Boolean out as a string I want to print out the numerical value.
    Latter I'll be using it in an API function that requires a boolean argument.
    Last edited by riely44; 12-08-2012 at 03:33 PM.

  4. #4
    Ultraviolence Connoisseur
    Join Date
    Mar 2004
    Posts
    555
    riely44 reread my post please, I explained how to print it as a numerical value you simply use %d.

  5. #5
    Registered User
    Join Date
    May 2010
    Posts
    15
    Remember that a boolean variable does not hold a string. It holds a value REPRESENTING true or false. So you can print it be testing the variable with an if/else statement and printing the right string (e.g. either "true" or "false").

    See the following:

    Code:
    #include <stdio.h>
    
    /**
     * Define our own boolean data type. The acceptable values
     * a variable of this type can hold is true or false.  Keep in mind
     * that enum's assign values to it's members sequentially (e.g. 0, 1, 2, 3, etc)
     * so that in the following, FALSE is 0 and TRUE is 1.
     */
    typedef enum bool { FALSE, TRUE } bool;
     
    typedef struct {
      char *name;
      bool pboolean;  /* no need to be a pointer, just holds true/false. */
    } mystruct;
     
    int main (int argc, char *argv[])
    {
       /**
        * Create a structure and assign values to it's members.
        * The members are name, which is assigned NULL (since it's a pointer),
        * and pboolean, a variable representing a true or false value.
        */
       mystruct data = { NULL, TRUE };
    
       mystruct *ptr_mystruct;
       ptr_mystruct = &data;
     
       ptr_mystruct->name = "me";
       printf("The name is: %s\n", ptr_mystruct->name);
       printf("The value is: %s\n", (ptr_mystruct->pboolean == TRUE) ? "True" : "False");
    
       return 0;
    }

  6. #6
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    This would be my suggestion
    Code:
    printf("The value is: %s\n", ptr_mystruct->pboolean ? "true" : "false");
    I bring this up often in code reviews: Boolean values should not be compared against true. All that does is takes one boolean expression e.g. (mybool) and builds a larger boolean expression that has the same effect. If you bother writing that unnecessary code, why stop there when you could do:
    Code:
    if ((mybool == true) == true)
    // or
    if (((mybool == true) == true) == true)
    I think that gets the point across.

    Also, when using anything other than a lowercase bool to store the boolean, you have a very real danger of getting strange results in your program. I.e. anything other than 0 is treated as true by the compiler. You can avoid getting your program act as if you have a variable that is simultaneously not true and not false when they are inadvertently given a strange value such as 42*, by always using if (myBOOL), or if (!myBOOL). Or if you're a purist who dislikes implicit conversion from int to bool, then always compare against FALSE, i.e.
    Code:
    if (myBOOL != FALSE)
    // or
    if (myBOOL == FALSE)
    Which follows the "anything but zero is true" rule, and will also work with other more strongly typed languages.

    *More commonly you can get into a situation when mixing C and VB where you can get either 0, 1, or -1 in the BOOL.
    Last edited by iMalc; 12-08-2012 at 04:26 PM.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  7. #7
    Ultraviolence Connoisseur
    Join Date
    Mar 2004
    Posts
    555
    Two problems I have with your suggestion iMalc. First of all The stdbool.h header does not define FALSE so I'm not sure why you think thats a good macro to use. Secondly using true or false really doesn't matter as both of them at least show clearly that the value is meant to be a bool value not any value that could be true (which could be a pointer, a positive integer, an allocated object etc...).

    From a maintenance standpoint this is much easier to read, consider the following code excerpt:
    Code:
    if (!p || !t)
      break;
    No way to tell if p and t are pointers or integers or what-have-you.

    vs.

    Code:
    if (p == NULL || t == false)
      break;
    Now we can tell without looking up what types p and t are respectively.

  8. #8
    Registered User
    Join Date
    Nov 2012
    Posts
    1,393
    Quote Originally Posted by riely44 View Post
    Code:
       ptr_mystruct->name = "me";
       printf("The name is: %s\n", ptr_mystruct->name);
    This works fine for printing the name member but how do I do the same for the Boolean member?
    I think the above comments missed the fact that pboolean is defined as a bool* -- maybe this was the source of confusion. You must allocate space for it first. Then remember to use * to dereference it when storing/reading the underlying bool

    Code:
       ptr_mystruct->pboolean = malloc(sizeof(bool));
       *ptr_mystruct->pboolean = true;
       printf("The pboolean is: %d\n", *ptr_mystruct->pboolean);
    Notice that malloc was not needed for your name example because you assigned the char* to a constant string literal, which already has (read-only) space allocated somewhere by the compiler.
    Last edited by c99tutorial; 12-08-2012 at 04:47 PM.

  9. #9
    Registered User
    Join Date
    Dec 2012
    Posts
    3
    Thank you c99tutorial, that's just what I needed.
    You also explained why my name example worked but pboolean didn't.

  10. #10
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    Quote Originally Posted by nonpuz View Post
    Two problems I have with your suggestion iMalc. First of all The stdbool.h header does not define FALSE so I'm not sure why you think thats a good macro to use.
    I had no intention of implying it was declared anywhere in particular, or that it is in any way better to use BOOL over bool. But if one is going to use the commonly defined BOOL, TRUE, and FALSE macros, then the above is the way to go about it such that you wont run into problems.
    Secondly using true or false really doesn't matter as both of them at least show clearly that the value is meant to be a bool value not any value that could be true (which could be a pointer, a positive integer, an allocated object etc...).
    I explained precisely when and why it does matter, and I was clearly talking about uppercase TRUE at that point. If you think it doesn't matter, then you haven't understood the scenario I was describing, and obviously haven't yet run into the problem that can arise in the real world.

    From a maintenance standpoint this is much easier to read, consider the following code excerpt:
    Code:
    if (!p || !t)
      break;
    No way to tell if p and t are pointers or integers or what-have-you.

    vs.

    Code:
    if (p == NULL || t == false)
      break;
    Now we can tell without looking up what types p and t are respectively.
    Straw man argument. You're writing it in a way that I would never suggest, and then tearing it down. Both of those are equally poor IMHO.
    If you follow what more strongly typed language such as Pascal enforce, then there is never any such ambiguity as to what the type must be. I.e. you would never do if (!p) for p being a pointer, because that has an implicit conversion from pointer to bool. The above would be written as:
    Code:
    if (p == NULL || !t).
    It really is much nicer to code as if you're in a strongly typed language. Anything that is or isnt a bool is perfectly obvious, as it requires using some comparison operator to turn it into a bool.

    That being said, its not disastrously wrong writing out (t == false) for example, it's just extra clutter.
    Some of the most annoying superflous code I've seen related to boolean logic is:
    Code:
    bool secondbool = firstbool ? true : false;
    I hope you'll agree that at least this one is a little absurd when it can obviously just be:
    Code:
    bool secondbool = firstbool;
    Last edited by iMalc; 12-08-2012 at 07:39 PM.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  11. #11
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    Quote Originally Posted by c99tutorial View Post
    I think the above comments missed the fact that pboolean is defined as a bool*
    You're right, I somehow totally missed that. that happens when it is something you would pretty much never expect.
    Edit: Oh I see why I missed that, I was looking at the post directly above mine.

    The correct solution there is almost certainly to change it to not be a pointer. One does not malloc a bool without a very very good reason.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Accessing array members
    By kkk in forum C Programming
    Replies: 1
    Last Post: 06-05-2011, 01:56 PM
  2. Accessing Structure Members
    By anndruu12 in forum C Programming
    Replies: 5
    Last Post: 12-02-2010, 02:37 AM
  3. accessing enum members
    By stanlvw in forum C++ Programming
    Replies: 1
    Last Post: 07-24-2008, 02:58 PM
  4. sorting structure members using pointers
    By robstr12 in forum C Programming
    Replies: 5
    Last Post: 07-25-2005, 05:50 PM
  5. Accessing structure members
    By foniks munkee in forum C Programming
    Replies: 18
    Last Post: 02-13-2002, 03:06 PM

Tags for this Thread