[Objective-C++]Why assigning object to BOOL type variable is allowed in 64bit but not in 32bit
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++
add a comment |
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++
add a comment |
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++
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++
objective-c c++11 32bit-64bit objective-c++
asked Nov 20 '18 at 2:11


Jintao OuJintao Ou
11017
11017
add a comment |
add a comment |
3 Answers
3
active
oldest
votes
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.)
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 beNSLog(@"%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 forOBJC_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
add a comment |
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];
add a comment |
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
add a comment |
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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.)
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 beNSLog(@"%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 forOBJC_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
add a comment |
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.)
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 beNSLog(@"%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 forOBJC_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
add a comment |
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.)
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.)
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 beNSLog(@"%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 forOBJC_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
add a comment |
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 beNSLog(@"%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 forOBJC_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
add a comment |
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];
add a comment |
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];
add a comment |
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];
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];
answered Nov 20 '18 at 4:06


trungductrungduc
8,37531239
8,37531239
add a comment |
add a comment |
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
add a comment |
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
add a comment |
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
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
edited Nov 20 '18 at 21:02
answered Nov 20 '18 at 4:13
Grady PlayerGrady Player
12.1k14168
12.1k14168
add a comment |
add a comment |
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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