ObjC should support NSNumber constants

Originator:alastair
Number:rdar://6406062 Date Originated:28-Nov-2008 04:13 AM
Status:Duplicate/4395455 Resolved:
Product:Developer Tools Product Version:GCC 4.2
Classification:Feature (New) Reproducible:Not applicable
 
* Summary:
ObjC currently supports NSString constants, with the syntax

  @"This is an NSString"

however it doesn't support NSNumber constants, which leads to an awful lot of code like

  [NSDictionary dictionaryWithObjectsAndKeys:
    [NSNumber numberWithInt:43], @"MyCount",
    [NSNumber numberWithBool:YES], @"MyBool",
    nil];

which is somewhat tedious to type.

It'd be helpful if ObjC could also support

  @43

and

  @yes/@no

which would turn the example above into

  [NSDictionary dictionaryWithObjectsAndKeys:
    @43, @"MyCount",
    @yes, @"MyBool",
    nil];

Comments

Re: Easier workaround

TL_FLOATARG is tremendously clever, but alas it will fail for integers near the maximum allowable values. This and the multiple evaluation can both be fixed if you ignore strict ANSI compatibility and use _builtintypes_compatible_p.

By michael.ash at Dec. 10, 2008, 10:24 p.m. (reply...)

For additional caveat fun, that builtin doesn’t exist in Objective-C++. Neither do various others, like _builtichoose_expr().

By jens.ayton at Dec. 11, 2008, 10:23 p.m. (reply...)

Rats, you are indeed right about the overflow. I had an uglier earlier version that may increase the usable range, but I haven't analyzed this either to see if it will behave when x/(x+1) is close to 1.0:

#define TL_FLOATARG(x) ( ((x) > 0) ? ((x) / ((x) + 1)) : ( (x) ? ((x) / ((x) - 1)) : (((x) + 1) / ((x) + 2)) ) )

And mostly for my future reference, here is the documentation for that built-in the comment system so helpfully mangled: http://gcc.gnu.org/onlinedocs/gcc-4.2.1/gcc/Other-Builtins.html

Easier workaround

I'd agree it be neat to have true NSNumber-like constants as a language feature, but the following macro is almost as good IMO:


#define TL_FLOATARG(x) ( (x) ? ((x) / (2 * (x))) : (((x) + 1) / 2) )
#define N(x) (TL_FLOATARG(x) ? [NSNumber numberWithDouble:(x)] : [NSNumber numberWithLong:(x)])


[NSArray arrayWithObjects: N(42), N(3.14), nil];

It is _STRICTANSI__ compatible (and thus must evaluate its arguments multiple times). I've got a longer explanation posted on my blog (Cocoa NSNumber "constant" macro for Objective-C) with a few more details.

Sure

Sure, you can do things like that, though it would still be nice to have a way to write an NSNumber constant.

Workaround?

Well, I suppose using macros can make you code looking slightly better:

#define NSINT(N$)  [NSNumber numberWithInt: (N$)]
#define NSBOOL(B$) [NSNumber numberWithBool: ((B$) != NO)]

NSINT(43)
NSBOOL(YES)
By al.skobelev at Dec. 4, 2008, 5:05 p.m. (reply...)

Please note: Reports posted here will not necessarily be seen by Apple. All problems should be submitted at bugreport.apple.com before they are posted here. Please only post information for Radars that you have filed yourself, and please do not include Apple confidential information in your posts. Thank you!