Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Any reason to not use parentheses for NSNumber literals?

I've been learning about modern Objective-C recently and started using the wonderful new syntax for NSNumber literals. After reading up there are actually two ways to create NSNumbers:

// NSNumber literal
NSNumber *a = @42;

// Boxed expression
NSNumber *a = @(42);    

The net result is the same (both generate an NSNumber with a value of 42), but are there any reasons to use the literal over the boxed expression for simple numeric constants?

I can see two style reasons to prefer boxed expressions:

  1. Easier to visually parse, especially if the number is negative or a macro (Xcode syntax highlighting doesn't correctly color @-1 or @INT_MAX).
  2. Easier to change to a non-constant expression later if needed without having to add the parentheses. Similar to the arguments about adding braces to single line if statements for "future proofing".

But are there any negatives or reasons to stick with the literal? The Clang page doesn't mention anything in the boxed expressions section that would indicate a loss of performance or other negative side effects.

So in the case of these simple numeric constants is this just a case of style?

like image 501
Kelly Avatar asked Mar 22 '23 14:03

Kelly


2 Answers

These in fact compile to the same assembly:

NSNumber *value = @42;
NSNumber *otherValue = @(42);

This leads to the following optimized assembly:

    // NSNumber *value = @42;

movl    L_OBJC_CLASSLIST_REFERENCES_$_-L0$pb(%edi), %eax <-- NSNumber
movl    L_OBJC_SELECTOR_REFERENCES_-L0$pb(%edi), %ecx    <-- numberWithInt:
movl    %ecx, 4(%esp)
movl    %eax, (%esp)
movl    $42, 8(%esp)   <-- Here's your value
calll   L_objc_msgSend$stub

    // NSNumber *value = @(42);

movl    L_OBJC_CLASSLIST_REFERENCES_$_-L0$pb(%edi), %eax <-- NSNumber
movl    L_OBJC_SELECTOR_REFERENCES_-L0$pb(%edi), %ecx    <-- numberWithInt:
movl    %ecx, 4(%esp)
movl    %eax, (%esp)
movl    $42, 8(%esp)  <--- and here again
calll   L_objc_msgSend$stub

It's worth noting that it's even smart enough to do pre-computing for you:

    // NSNumber *value = @(42 + 1);

movl    L_OBJC_CLASSLIST_REFERENCES_$_-L0$pb(%edi), %eax <-- NSNumber
movl    L_OBJC_SELECTOR_REFERENCES_-L0$pb(%edi), %ecx    <-- numberWithInt:
movl    %ecx, 4(%esp)
movl    %eax, (%esp)
movl    $43, 8(%esp)  <--- Hey; it's precomputed to 43. Nice.
calll   L_objc_msgSend$stub

So as @Zaph says, it doesn't matter to the compiler.

like image 141
Rob Napier Avatar answered Apr 05 '23 23:04

Rob Napier


Since each case actually "boxes" the integer into an object it is an issue of clarity, similar to adding extra "()" for operator precedence when they are not needed.
Ex: 2+3*4 vs: 2+(3*4)

Personally I write @42 not @(42)
but @(kMeaningOfLifeAndEverything) is OK ;-)

like image 29
zaph Avatar answered Apr 05 '23 22:04

zaph