[Objective-C++]Why assigning object to BOOL type variable is allowed in 64bit but not in 32bit












0















The following code in ViewController.mm, would be compiled successfully(without any warning or error) in 64 bit environment.



- (void)viewDidLoad {
[super viewDidLoad];
BOOL var = [[NSUserDefaults standardUserDefaults] objectForKey:@"foo"];
NSLog(@"%d", var);
}


But when I change the running target to a 32 bit device(e.g, iPhone 5), it show me error like this:



 Cannot initialize a variable of type 'BOOL' (aka 'signed char') with an rvalue of type 'id _Nullable'


I do know this assignment is wroing, but why it allowed in first situation?










share|improve this question



























    0















    The following code in ViewController.mm, would be compiled successfully(without any warning or error) in 64 bit environment.



    - (void)viewDidLoad {
    [super viewDidLoad];
    BOOL var = [[NSUserDefaults standardUserDefaults] objectForKey:@"foo"];
    NSLog(@"%d", var);
    }


    But when I change the running target to a 32 bit device(e.g, iPhone 5), it show me error like this:



     Cannot initialize a variable of type 'BOOL' (aka 'signed char') with an rvalue of type 'id _Nullable'


    I do know this assignment is wroing, but why it allowed in first situation?










    share|improve this question

























      0












      0








      0








      The following code in ViewController.mm, would be compiled successfully(without any warning or error) in 64 bit environment.



      - (void)viewDidLoad {
      [super viewDidLoad];
      BOOL var = [[NSUserDefaults standardUserDefaults] objectForKey:@"foo"];
      NSLog(@"%d", var);
      }


      But when I change the running target to a 32 bit device(e.g, iPhone 5), it show me error like this:



       Cannot initialize a variable of type 'BOOL' (aka 'signed char') with an rvalue of type 'id _Nullable'


      I do know this assignment is wroing, but why it allowed in first situation?










      share|improve this question














      The following code in ViewController.mm, would be compiled successfully(without any warning or error) in 64 bit environment.



      - (void)viewDidLoad {
      [super viewDidLoad];
      BOOL var = [[NSUserDefaults standardUserDefaults] objectForKey:@"foo"];
      NSLog(@"%d", var);
      }


      But when I change the running target to a 32 bit device(e.g, iPhone 5), it show me error like this:



       Cannot initialize a variable of type 'BOOL' (aka 'signed char') with an rvalue of type 'id _Nullable'


      I do know this assignment is wroing, but why it allowed in first situation?







      objective-c c++11 32bit-64bit objective-c++






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Nov 20 '18 at 2:11









      Jintao OuJintao Ou

      11017




      11017
























          3 Answers
          3






          active

          oldest

          votes


















          2














          For 64-bit iOS, the BOOL type uses the C99 _Bool type (sometimes also available as bool). That type is defined to only have two values, 0 or 1. Assigning any other value to a variable of that type causes it to take on the value 1. (That is, all non-zero values become 1.)



          So, the assignment won't truncate the bitwise value, potentially converting a non-zero value to zero. Therefore, it's "safe" in a certain respect and there's no cause for a warning. (It might still be surprising for a naive developer who didn't understand the difference between an object's pointer and its value, as other answers have addressed, but that's a different thing.)






          share|improve this answer


























          • well that isn't the case here I will put a test on my answer.

            – Grady Player
            Nov 20 '18 at 21:01











          • actually the simplest example would be NSLog(@"%d",(BOOL)256);

            – Grady Player
            Nov 20 '18 at 21:04











          • @GradyPlayer, it's different between macOS and iOS. See /usr/include/objc/objc.h where it determines the default setting for OBJC_BOOL_IS_BOOL.

            – Ken Thomases
            Nov 20 '18 at 21:37











          • ok that may be... I would argue that it is still bad if it isn't guaranteed at a language level... I mean if I made the counter argument I would be downvoted to death...

            – Grady Player
            Nov 20 '18 at 22:10






          • 1





            @GradyPlayer The question was about why the compiler complained in one case (32-bit) but not the other (64-bit), not how to code it correctly. Nobody's saying that the code was good. Even the OP stated that the original code was buggy and they understood why.

            – Ken Thomases
            Nov 20 '18 at 23:51



















          1














          The error says that you are assigning an object to a variable of type BOOL. To resolve it, you need to convert object returned from objectForKey: to a BOOL variable by using boolValue.



          BOOL var = [[[NSUserDefaults standardUserDefaults] objectForKey:@"foo"] boolValue];





          share|improve this answer































            1














            your code:
            BOOL var = [[NSUserDefaults standardUserDefaults] objectForKey:@"foo"];

            is assigning an object's address to essentially an int of some size...



            This is almost always not what you want. You probably want:
            BOOL var = [[[NSUserDefaults standardUserDefaults] objectForKey:@"foo"]boolValue];



            If you do want to assign based on the presence of that object you could do:
            BOOL var = !![[NSUserDefaults standardUserDefaults] objectForKey:@"foo"];



            The reason is that if the bottom 8 bits of the address were to happen to all be 0's it could be a valid object, but would be a false value, which would be the result of the truncated assignment.



            int main(int argc, const char * argv) {

            BOOL b = 2;
            if (b == YES)
            {
            NSLog(@"I guess you are right");
            }else{
            NSLog(@"nope");
            }


            prints: nope






            share|improve this answer

























              Your Answer






              StackExchange.ifUsing("editor", function () {
              StackExchange.using("externalEditor", function () {
              StackExchange.using("snippets", function () {
              StackExchange.snippets.init();
              });
              });
              }, "code-snippets");

              StackExchange.ready(function() {
              var channelOptions = {
              tags: "".split(" "),
              id: "1"
              };
              initTagRenderer("".split(" "), "".split(" "), channelOptions);

              StackExchange.using("externalEditor", function() {
              // Have to fire editor after snippets, if snippets enabled
              if (StackExchange.settings.snippets.snippetsEnabled) {
              StackExchange.using("snippets", function() {
              createEditor();
              });
              }
              else {
              createEditor();
              }
              });

              function createEditor() {
              StackExchange.prepareEditor({
              heartbeatType: 'answer',
              autoActivateHeartbeat: false,
              convertImagesToLinks: true,
              noModals: true,
              showLowRepImageUploadWarning: true,
              reputationToPostImages: 10,
              bindNavPrevention: true,
              postfix: "",
              imageUploader: {
              brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
              contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
              allowUrls: true
              },
              onDemand: true,
              discardSelector: ".discard-answer"
              ,immediatelyShowMarkdownHelp:true
              });


              }
              });














              draft saved

              draft discarded


















              StackExchange.ready(
              function () {
              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53385246%2fobjective-cwhy-assigning-object-to-bool-type-variable-is-allowed-in-64bit-bu%23new-answer', 'question_page');
              }
              );

              Post as a guest















              Required, but never shown

























              3 Answers
              3






              active

              oldest

              votes








              3 Answers
              3






              active

              oldest

              votes









              active

              oldest

              votes






              active

              oldest

              votes









              2














              For 64-bit iOS, the BOOL type uses the C99 _Bool type (sometimes also available as bool). That type is defined to only have two values, 0 or 1. Assigning any other value to a variable of that type causes it to take on the value 1. (That is, all non-zero values become 1.)



              So, the assignment won't truncate the bitwise value, potentially converting a non-zero value to zero. Therefore, it's "safe" in a certain respect and there's no cause for a warning. (It might still be surprising for a naive developer who didn't understand the difference between an object's pointer and its value, as other answers have addressed, but that's a different thing.)






              share|improve this answer


























              • well that isn't the case here I will put a test on my answer.

                – Grady Player
                Nov 20 '18 at 21:01











              • actually the simplest example would be NSLog(@"%d",(BOOL)256);

                – Grady Player
                Nov 20 '18 at 21:04











              • @GradyPlayer, it's different between macOS and iOS. See /usr/include/objc/objc.h where it determines the default setting for OBJC_BOOL_IS_BOOL.

                – Ken Thomases
                Nov 20 '18 at 21:37











              • ok that may be... I would argue that it is still bad if it isn't guaranteed at a language level... I mean if I made the counter argument I would be downvoted to death...

                – Grady Player
                Nov 20 '18 at 22:10






              • 1





                @GradyPlayer The question was about why the compiler complained in one case (32-bit) but not the other (64-bit), not how to code it correctly. Nobody's saying that the code was good. Even the OP stated that the original code was buggy and they understood why.

                – Ken Thomases
                Nov 20 '18 at 23:51
















              2














              For 64-bit iOS, the BOOL type uses the C99 _Bool type (sometimes also available as bool). That type is defined to only have two values, 0 or 1. Assigning any other value to a variable of that type causes it to take on the value 1. (That is, all non-zero values become 1.)



              So, the assignment won't truncate the bitwise value, potentially converting a non-zero value to zero. Therefore, it's "safe" in a certain respect and there's no cause for a warning. (It might still be surprising for a naive developer who didn't understand the difference between an object's pointer and its value, as other answers have addressed, but that's a different thing.)






              share|improve this answer


























              • well that isn't the case here I will put a test on my answer.

                – Grady Player
                Nov 20 '18 at 21:01











              • actually the simplest example would be NSLog(@"%d",(BOOL)256);

                – Grady Player
                Nov 20 '18 at 21:04











              • @GradyPlayer, it's different between macOS and iOS. See /usr/include/objc/objc.h where it determines the default setting for OBJC_BOOL_IS_BOOL.

                – Ken Thomases
                Nov 20 '18 at 21:37











              • ok that may be... I would argue that it is still bad if it isn't guaranteed at a language level... I mean if I made the counter argument I would be downvoted to death...

                – Grady Player
                Nov 20 '18 at 22:10






              • 1





                @GradyPlayer The question was about why the compiler complained in one case (32-bit) but not the other (64-bit), not how to code it correctly. Nobody's saying that the code was good. Even the OP stated that the original code was buggy and they understood why.

                – Ken Thomases
                Nov 20 '18 at 23:51














              2












              2








              2







              For 64-bit iOS, the BOOL type uses the C99 _Bool type (sometimes also available as bool). That type is defined to only have two values, 0 or 1. Assigning any other value to a variable of that type causes it to take on the value 1. (That is, all non-zero values become 1.)



              So, the assignment won't truncate the bitwise value, potentially converting a non-zero value to zero. Therefore, it's "safe" in a certain respect and there's no cause for a warning. (It might still be surprising for a naive developer who didn't understand the difference between an object's pointer and its value, as other answers have addressed, but that's a different thing.)






              share|improve this answer















              For 64-bit iOS, the BOOL type uses the C99 _Bool type (sometimes also available as bool). That type is defined to only have two values, 0 or 1. Assigning any other value to a variable of that type causes it to take on the value 1. (That is, all non-zero values become 1.)



              So, the assignment won't truncate the bitwise value, potentially converting a non-zero value to zero. Therefore, it's "safe" in a certain respect and there's no cause for a warning. (It might still be surprising for a naive developer who didn't understand the difference between an object's pointer and its value, as other answers have addressed, but that's a different thing.)







              share|improve this answer














              share|improve this answer



              share|improve this answer








              edited Nov 20 '18 at 21:38

























              answered Nov 20 '18 at 4:41









              Ken ThomasesKen Thomases

              69.5k669106




              69.5k669106













              • well that isn't the case here I will put a test on my answer.

                – Grady Player
                Nov 20 '18 at 21:01











              • actually the simplest example would be NSLog(@"%d",(BOOL)256);

                – Grady Player
                Nov 20 '18 at 21:04











              • @GradyPlayer, it's different between macOS and iOS. See /usr/include/objc/objc.h where it determines the default setting for OBJC_BOOL_IS_BOOL.

                – Ken Thomases
                Nov 20 '18 at 21:37











              • ok that may be... I would argue that it is still bad if it isn't guaranteed at a language level... I mean if I made the counter argument I would be downvoted to death...

                – Grady Player
                Nov 20 '18 at 22:10






              • 1





                @GradyPlayer The question was about why the compiler complained in one case (32-bit) but not the other (64-bit), not how to code it correctly. Nobody's saying that the code was good. Even the OP stated that the original code was buggy and they understood why.

                – Ken Thomases
                Nov 20 '18 at 23:51



















              • well that isn't the case here I will put a test on my answer.

                – Grady Player
                Nov 20 '18 at 21:01











              • actually the simplest example would be NSLog(@"%d",(BOOL)256);

                – Grady Player
                Nov 20 '18 at 21:04











              • @GradyPlayer, it's different between macOS and iOS. See /usr/include/objc/objc.h where it determines the default setting for OBJC_BOOL_IS_BOOL.

                – Ken Thomases
                Nov 20 '18 at 21:37











              • ok that may be... I would argue that it is still bad if it isn't guaranteed at a language level... I mean if I made the counter argument I would be downvoted to death...

                – Grady Player
                Nov 20 '18 at 22:10






              • 1





                @GradyPlayer The question was about why the compiler complained in one case (32-bit) but not the other (64-bit), not how to code it correctly. Nobody's saying that the code was good. Even the OP stated that the original code was buggy and they understood why.

                – Ken Thomases
                Nov 20 '18 at 23:51

















              well that isn't the case here I will put a test on my answer.

              – Grady Player
              Nov 20 '18 at 21:01





              well that isn't the case here I will put a test on my answer.

              – Grady Player
              Nov 20 '18 at 21:01













              actually the simplest example would be NSLog(@"%d",(BOOL)256);

              – Grady Player
              Nov 20 '18 at 21:04





              actually the simplest example would be NSLog(@"%d",(BOOL)256);

              – Grady Player
              Nov 20 '18 at 21:04













              @GradyPlayer, it's different between macOS and iOS. See /usr/include/objc/objc.h where it determines the default setting for OBJC_BOOL_IS_BOOL.

              – Ken Thomases
              Nov 20 '18 at 21:37





              @GradyPlayer, it's different between macOS and iOS. See /usr/include/objc/objc.h where it determines the default setting for OBJC_BOOL_IS_BOOL.

              – Ken Thomases
              Nov 20 '18 at 21:37













              ok that may be... I would argue that it is still bad if it isn't guaranteed at a language level... I mean if I made the counter argument I would be downvoted to death...

              – Grady Player
              Nov 20 '18 at 22:10





              ok that may be... I would argue that it is still bad if it isn't guaranteed at a language level... I mean if I made the counter argument I would be downvoted to death...

              – Grady Player
              Nov 20 '18 at 22:10




              1




              1





              @GradyPlayer The question was about why the compiler complained in one case (32-bit) but not the other (64-bit), not how to code it correctly. Nobody's saying that the code was good. Even the OP stated that the original code was buggy and they understood why.

              – Ken Thomases
              Nov 20 '18 at 23:51





              @GradyPlayer The question was about why the compiler complained in one case (32-bit) but not the other (64-bit), not how to code it correctly. Nobody's saying that the code was good. Even the OP stated that the original code was buggy and they understood why.

              – Ken Thomases
              Nov 20 '18 at 23:51













              1














              The error says that you are assigning an object to a variable of type BOOL. To resolve it, you need to convert object returned from objectForKey: to a BOOL variable by using boolValue.



              BOOL var = [[[NSUserDefaults standardUserDefaults] objectForKey:@"foo"] boolValue];





              share|improve this answer




























                1














                The error says that you are assigning an object to a variable of type BOOL. To resolve it, you need to convert object returned from objectForKey: to a BOOL variable by using boolValue.



                BOOL var = [[[NSUserDefaults standardUserDefaults] objectForKey:@"foo"] boolValue];





                share|improve this answer


























                  1












                  1








                  1







                  The error says that you are assigning an object to a variable of type BOOL. To resolve it, you need to convert object returned from objectForKey: to a BOOL variable by using boolValue.



                  BOOL var = [[[NSUserDefaults standardUserDefaults] objectForKey:@"foo"] boolValue];





                  share|improve this answer













                  The error says that you are assigning an object to a variable of type BOOL. To resolve it, you need to convert object returned from objectForKey: to a BOOL variable by using boolValue.



                  BOOL var = [[[NSUserDefaults standardUserDefaults] objectForKey:@"foo"] boolValue];






                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Nov 20 '18 at 4:06









                  trungductrungduc

                  8,37531239




                  8,37531239























                      1














                      your code:
                      BOOL var = [[NSUserDefaults standardUserDefaults] objectForKey:@"foo"];

                      is assigning an object's address to essentially an int of some size...



                      This is almost always not what you want. You probably want:
                      BOOL var = [[[NSUserDefaults standardUserDefaults] objectForKey:@"foo"]boolValue];



                      If you do want to assign based on the presence of that object you could do:
                      BOOL var = !![[NSUserDefaults standardUserDefaults] objectForKey:@"foo"];



                      The reason is that if the bottom 8 bits of the address were to happen to all be 0's it could be a valid object, but would be a false value, which would be the result of the truncated assignment.



                      int main(int argc, const char * argv) {

                      BOOL b = 2;
                      if (b == YES)
                      {
                      NSLog(@"I guess you are right");
                      }else{
                      NSLog(@"nope");
                      }


                      prints: nope






                      share|improve this answer






























                        1














                        your code:
                        BOOL var = [[NSUserDefaults standardUserDefaults] objectForKey:@"foo"];

                        is assigning an object's address to essentially an int of some size...



                        This is almost always not what you want. You probably want:
                        BOOL var = [[[NSUserDefaults standardUserDefaults] objectForKey:@"foo"]boolValue];



                        If you do want to assign based on the presence of that object you could do:
                        BOOL var = !![[NSUserDefaults standardUserDefaults] objectForKey:@"foo"];



                        The reason is that if the bottom 8 bits of the address were to happen to all be 0's it could be a valid object, but would be a false value, which would be the result of the truncated assignment.



                        int main(int argc, const char * argv) {

                        BOOL b = 2;
                        if (b == YES)
                        {
                        NSLog(@"I guess you are right");
                        }else{
                        NSLog(@"nope");
                        }


                        prints: nope






                        share|improve this answer




























                          1












                          1








                          1







                          your code:
                          BOOL var = [[NSUserDefaults standardUserDefaults] objectForKey:@"foo"];

                          is assigning an object's address to essentially an int of some size...



                          This is almost always not what you want. You probably want:
                          BOOL var = [[[NSUserDefaults standardUserDefaults] objectForKey:@"foo"]boolValue];



                          If you do want to assign based on the presence of that object you could do:
                          BOOL var = !![[NSUserDefaults standardUserDefaults] objectForKey:@"foo"];



                          The reason is that if the bottom 8 bits of the address were to happen to all be 0's it could be a valid object, but would be a false value, which would be the result of the truncated assignment.



                          int main(int argc, const char * argv) {

                          BOOL b = 2;
                          if (b == YES)
                          {
                          NSLog(@"I guess you are right");
                          }else{
                          NSLog(@"nope");
                          }


                          prints: nope






                          share|improve this answer















                          your code:
                          BOOL var = [[NSUserDefaults standardUserDefaults] objectForKey:@"foo"];

                          is assigning an object's address to essentially an int of some size...



                          This is almost always not what you want. You probably want:
                          BOOL var = [[[NSUserDefaults standardUserDefaults] objectForKey:@"foo"]boolValue];



                          If you do want to assign based on the presence of that object you could do:
                          BOOL var = !![[NSUserDefaults standardUserDefaults] objectForKey:@"foo"];



                          The reason is that if the bottom 8 bits of the address were to happen to all be 0's it could be a valid object, but would be a false value, which would be the result of the truncated assignment.



                          int main(int argc, const char * argv) {

                          BOOL b = 2;
                          if (b == YES)
                          {
                          NSLog(@"I guess you are right");
                          }else{
                          NSLog(@"nope");
                          }


                          prints: nope







                          share|improve this answer














                          share|improve this answer



                          share|improve this answer








                          edited Nov 20 '18 at 21:02

























                          answered Nov 20 '18 at 4:13









                          Grady PlayerGrady Player

                          12.1k14168




                          12.1k14168






























                              draft saved

                              draft discarded




















































                              Thanks for contributing an answer to Stack Overflow!


                              • Please be sure to answer the question. Provide details and share your research!

                              But avoid



                              • Asking for help, clarification, or responding to other answers.

                              • Making statements based on opinion; back them up with references or personal experience.


                              To learn more, see our tips on writing great answers.




                              draft saved


                              draft discarded














                              StackExchange.ready(
                              function () {
                              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53385246%2fobjective-cwhy-assigning-object-to-bool-type-variable-is-allowed-in-64bit-bu%23new-answer', 'question_page');
                              }
                              );

                              Post as a guest















                              Required, but never shown





















































                              Required, but never shown














                              Required, but never shown












                              Required, but never shown







                              Required, but never shown

































                              Required, but never shown














                              Required, but never shown












                              Required, but never shown







                              Required, but never shown







                              Popular posts from this blog

                              MongoDB - Not Authorized To Execute Command

                              How to fix TextFormField cause rebuild widget in Flutter

                              Npm cannot find a required file even through it is in the searched directory