8 Three new features were introduced into clang at the same time:
9 *NSNumber Literals* provide a syntax for creating ``NSNumber`` from
10 scalar literal expressions; *Collection Literals* provide a short-hand
11 for creating arrays and dictionaries; *Object Subscripting* provides a
12 way to use subscripting with Objective-C objects. Users of Apple
13 compiler releases can use these features starting with the Apple LLVM
14 Compiler 4.0. Users of open-source LLVM.org compiler releases can use
15 these features starting with clang v3.1.
17 These language additions simplify common Objective-C programming
18 patterns, make programs more concise, and improve the safety of
21 This document describes how the features are implemented in clang, and
22 how to use them in your own programs.
27 The framework class ``NSNumber`` is used to wrap scalar values inside
28 objects: signed and unsigned integers (``char``, ``short``, ``int``,
29 ``long``, ``long long``), floating point numbers (``float``,
30 ``double``), and boolean values (``BOOL``, C++ ``bool``). Scalar values
31 wrapped in objects are also known as *boxed* values.
33 In Objective-C, any character, numeric or boolean literal prefixed with
34 the ``'@'`` character will evaluate to a pointer to an ``NSNumber``
35 object initialized with that value. C's type suffixes may be used to
36 control the size of numeric literals.
41 The following program illustrates the rules for ``NSNumber`` literals:
45 void main(int argc, const char *argv[]) {
46 // character literals.
47 NSNumber *theLetterZ = @'Z'; // equivalent to [NSNumber numberWithChar:'Z']
50 NSNumber *fortyTwo = @42; // equivalent to [NSNumber numberWithInt:42]
51 NSNumber *fortyTwoUnsigned = @42U; // equivalent to [NSNumber numberWithUnsignedInt:42U]
52 NSNumber *fortyTwoLong = @42L; // equivalent to [NSNumber numberWithLong:42L]
53 NSNumber *fortyTwoLongLong = @42LL; // equivalent to [NSNumber numberWithLongLong:42LL]
55 // floating point literals.
56 NSNumber *piFloat = @3.141592654F; // equivalent to [NSNumber numberWithFloat:3.141592654F]
57 NSNumber *piDouble = @3.1415926535; // equivalent to [NSNumber numberWithDouble:3.1415926535]
60 NSNumber *yesNumber = @YES; // equivalent to [NSNumber numberWithBool:YES]
61 NSNumber *noNumber = @NO; // equivalent to [NSNumber numberWithBool:NO]
64 NSNumber *trueNumber = @true; // equivalent to [NSNumber numberWithBool:(BOOL)true]
65 NSNumber *falseNumber = @false; // equivalent to [NSNumber numberWithBool:(BOOL)false]
72 NSNumber literals only support literal scalar values after the ``'@'``.
73 Consequently, ``@INT_MAX`` works, but ``@INT_MIN`` does not, because
74 they are defined like this:
78 #define INT_MAX 2147483647 /* max value for an int */
79 #define INT_MIN (-2147483647-1) /* min value for an int */
81 The definition of ``INT_MIN`` is not a simple literal, but a
82 parenthesized expression. Parenthesized expressions are supported using
83 the `boxed expression <#objc_boxed_expressions>`_ syntax, which is
84 described in the next section.
86 Because ``NSNumber`` does not currently support wrapping ``long double``
87 values, the use of a ``long double NSNumber`` literal (e.g.
88 ``@123.23L``) will be rejected by the compiler.
90 Previously, the ``BOOL`` type was simply a typedef for ``signed char``,
91 and ``YES`` and ``NO`` were macros that expand to ``(BOOL)1`` and
92 ``(BOOL)0`` respectively. To support ``@YES`` and ``@NO`` expressions,
93 these macros are now defined using new language keywords in
94 ``<objc/objc.h>``:
98 #if __has_feature(objc_bool)
99 #define YES __objc_yes
102 #define YES ((BOOL)1)
106 The compiler implicitly converts ``__objc_yes`` and ``__objc_no`` to
107 ``(BOOL)1`` and ``(BOOL)0``. The keywords are used to disambiguate
108 ``BOOL`` and integer literals.
110 Objective-C++ also supports ``@true`` and ``@false`` expressions, which
111 are equivalent to ``@YES`` and ``@NO``.
116 Objective-C provides a new syntax for boxing C expressions:
122 Expressions of scalar (numeric, enumerated, BOOL) and C string pointer
128 NSNumber *smallestInt = @(-INT_MAX - 1); // [NSNumber numberWithInt:(-INT_MAX - 1)]
129 NSNumber *piOverTwo = @(M_PI / 2); // [NSNumber numberWithDouble:(M_PI / 2)]
132 typedef enum { Red, Green, Blue } Color;
133 NSNumber *favoriteColor = @(Green); // [NSNumber numberWithInt:((int)Green)]
136 NSString *path = @(getenv("PATH")); // [NSString stringWithUTF8String:(getenv("PATH"))]
137 NSArray *pathComponents = [path componentsSeparatedByString:@":"];
142 Cocoa frameworks frequently define constant values using *enums.*
143 Although enum values are integral, they may not be used directly as
144 boxed literals (this avoids conflicts with future ``'@'``-prefixed
145 Objective-C keywords). Instead, an enum value must be placed inside a
146 boxed expression. The following example demonstrates configuring an
147 ``AVAudioRecorder`` using a dictionary that contains a boxed enumeration
153 AVAudioQualityMin = 0,
154 AVAudioQualityLow = 0x20,
155 AVAudioQualityMedium = 0x40,
156 AVAudioQualityHigh = 0x60,
157 AVAudioQualityMax = 0x7F
160 - (AVAudioRecorder *)recordToFile:(NSURL *)fileURL {
161 NSDictionary *settings = @{ AVEncoderAudioQualityKey : @(AVAudioQualityMax) };
162 return [[AVAudioRecorder alloc] initWithURL:fileURL settings:settings error:NULL];
165 The expression ``@(AVAudioQualityMax)`` converts ``AVAudioQualityMax``
166 to an integer type, and boxes the value accordingly. If the enum has a
167 :ref:`fixed underlying type <objc-fixed-enum>` as in:
171 typedef enum : unsigned char { Red, Green, Blue } Color;
172 NSNumber *red = @(Red), *green = @(Green), *blue = @(Blue); // => [NSNumber numberWithUnsignedChar:]
174 then the fixed underlying type will be used to select the correct
175 ``NSNumber`` creation method.
177 Boxing a value of enum type will result in a ``NSNumber`` pointer with a
178 creation method according to the underlying type of the enum, which can
179 be a :ref:`fixed underlying type <objc-fixed-enum>`
180 or a compiler-defined integer type capable of representing the values of
181 all the members of the enumeration:
185 typedef enum : unsigned char { Red, Green, Blue } Color;
187 NSNumber *nsCol = @(col); // => [NSNumber numberWithUnsignedChar:]
192 A C string literal prefixed by the ``'@'`` token denotes an ``NSString``
193 literal in the same way a numeric literal prefixed by the ``'@'`` token
194 denotes an ``NSNumber`` literal. When the type of the parenthesized
195 expression is ``(char *)`` or ``(const char *)``, the result of the
196 boxed expression is a pointer to an ``NSString`` object containing
197 equivalent character data, which is assumed to be '\\0'-terminated and
198 UTF-8 encoded. The following example converts C-style command line
199 arguments into ``NSString`` objects.
203 // Partition command line arguments into positional and option arguments.
204 NSMutableArray *args = [NSMutableArray new];
205 NSMutableDictionary *options = [NSMutableDictionary new];
207 const char *arg = *++argv;
208 if (strncmp(arg, "--", 2) == 0) {
209 options[@(arg + 2)] = @(*++argv); // --key value
211 [args addObject:@(arg)]; // positional argument
215 As with all C pointers, character pointer expressions can involve
216 arbitrary pointer arithmetic, therefore programmers must ensure that the
217 character data is valid. Passing ``NULL`` as the character pointer will
218 raise an exception at runtime. When possible, the compiler will reject
219 ``NULL`` character pointers used in boxed expressions.
224 Boxed expressions will be available in clang 3.2. It is not currently
225 available in any Apple compiler.
230 Objective-C now supports a new expression syntax for creating immutable
231 array and dictionary container objects.
236 Immutable array expression:
240 NSArray *array = @[ @"Hello", NSApp, [NSNumber numberWithInt:42] ];
242 This creates an ``NSArray`` with 3 elements. The comma-separated
243 sub-expressions of an array literal can be any Objective-C object
244 pointer typed expression.
246 Immutable dictionary expression:
250 NSDictionary *dictionary = @{
251 @"name" : NSUserName(),
252 @"date" : [NSDate date],
253 @"processInfo" : [NSProcessInfo processInfo]
256 This creates an ``NSDictionary`` with 3 key/value pairs. Value
257 sub-expressions of a dictionary literal must be Objective-C object
258 pointer typed, as in array literals. Key sub-expressions must be of an
259 Objective-C object pointer type that implements the
260 ``<NSCopying>`` protocol.
265 Neither keys nor values can have the value ``nil`` in containers. If the
266 compiler can prove that a key or value is ``nil`` at compile time, then
267 a warning will be emitted. Otherwise, a runtime error will occur.
269 Using array and dictionary literals is safer than the variadic creation
270 forms commonly in use today. Array literal expressions expand to calls
271 to ``+[NSArray arrayWithObjects:count:]``, which validates that all
272 objects are non-``nil``. The variadic form,
273 ``+[NSArray arrayWithObjects:]`` uses ``nil`` as an argument list
274 terminator, which can lead to malformed array objects. Dictionary
275 literals are similarly created with
276 ``+[NSDictionary dictionaryWithObjects:forKeys:count:]`` which validates
277 all objects and keys, unlike
278 ``+[NSDictionary dictionaryWithObjectsAndKeys:]`` which also uses a
279 ``nil`` parameter as an argument list terminator.
284 Objective-C object pointer values can now be used with C's subscripting
290 The following code demonstrates the use of object subscripting syntax
291 with ``NSMutableArray`` and ``NSMutableDictionary`` objects:
295 NSMutableArray *array = ...;
296 NSUInteger idx = ...;
298 id oldObject = array[idx];
299 array[idx] = newObject; // replace oldObject with newObject
301 NSMutableDictionary *dictionary = ...;
303 oldObject = dictionary[key];
304 dictionary[key] = newObject; // replace oldObject with newObject
306 The next section explains how subscripting expressions map to accessor
312 Objective-C supports two kinds of subscript expressions: *array-style*
313 subscript expressions use integer typed subscripts; *dictionary-style*
314 subscript expressions use Objective-C object pointer typed subscripts.
315 Each type of subscript expression is mapped to a message send using a
316 predefined selector. The advantage of this design is flexibility: class
317 designers are free to introduce subscripting by declaring methods or by
318 adopting protocols. Moreover, because the method names are selected by
319 the type of the subscript, an object can be subscripted using both array
320 and dictionary styles.
322 Array-Style Subscripting
323 ^^^^^^^^^^^^^^^^^^^^^^^^
325 When the subscript operand has an integral type, the expression is
326 rewritten to use one of two different selectors, depending on whether
327 the element is being read or written. When an expression reads an
328 element using an integral index, as in the following example:
332 NSUInteger idx = ...;
333 id value = object[idx];
335 it is translated into a call to ``objectAtIndexedSubscript:``
339 id value = [object objectAtIndexedSubscript:idx];
341 When an expression writes an element using an integral index:
345 object[idx] = newValue;
347 it is translated to a call to ``setObject:atIndexedSubscript:``
351 [object setObject:newValue atIndexedSubscript:idx];
353 These message sends are then type-checked and performed just like
354 explicit message sends. The method used for objectAtIndexedSubscript:
355 must be declared with an argument of integral type and a return value of
356 some Objective-C object pointer type. The method used for
357 setObject:atIndexedSubscript: must be declared with its first argument
358 having some Objective-C pointer type and its second argument having
361 The meaning of indexes is left up to the declaring class. The compiler
362 will coerce the index to the appropriate argument type of the method it
363 uses for type-checking. For an instance of ``NSArray``, reading an
364 element using an index outside the range ``[0, array.count)`` will raise
365 an exception. For an instance of ``NSMutableArray``, assigning to an
366 element using an index within this range will replace that element, but
367 assigning to an element using an index outside this range will raise an
368 exception; no syntax is provided for inserting, appending, or removing
369 elements for mutable arrays.
371 A class need not declare both methods in order to take advantage of this
372 language feature. For example, the class ``NSArray`` declares only
373 ``objectAtIndexedSubscript:``, so that assignments to elements will fail
374 to type-check; moreover, its subclass ``NSMutableArray`` declares
375 ``setObject:atIndexedSubscript:``.
377 Dictionary-Style Subscripting
378 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
380 When the subscript operand has an Objective-C object pointer type, the
381 expression is rewritten to use one of two different selectors, depending
382 on whether the element is being read from or written to. When an
383 expression reads an element using an Objective-C object pointer
384 subscript operand, as in the following example:
389 id value = object[key];
391 it is translated into a call to the ``objectForKeyedSubscript:`` method:
395 id value = [object objectForKeyedSubscript:key];
397 When an expression writes an element using an Objective-C object pointer
402 object[key] = newValue;
404 it is translated to a call to ``setObject:forKeyedSubscript:``
408 [object setObject:newValue forKeyedSubscript:key];
410 The behavior of ``setObject:forKeyedSubscript:`` is class-specific; but
411 in general it should replace an existing value if one is already
412 associated with a key, otherwise it should add a new value for the key.
413 No syntax is provided for removing elements from mutable dictionaries.
418 An Objective-C subscript expression occurs when the base operand of the
419 C subscript operator has an Objective-C object pointer type. Since this
420 potentially collides with pointer arithmetic on the value, these
421 expressions are only supported under the modern Objective-C runtime,
422 which categorically forbids such arithmetic.
424 Currently, only subscripts of integral or Objective-C object pointer
425 type are supported. In C++, a class type can be used if it has a single
426 conversion function to an integral or Objective-C pointer type, in which
427 case that conversion is applied and analysis continues as appropriate.
428 Otherwise, the expression is ill-formed.
430 An Objective-C object subscript expression is always an l-value. If the
431 expression appears on the left-hand side of a simple assignment operator
432 (=), the element is written as described below. If the expression
433 appears on the left-hand side of a compound assignment operator (e.g.
434 +=), the program is ill-formed, because the result of reading an element
435 is always an Objective-C object pointer and no binary operators are
436 legal on such pointers. If the expression appears in any other position,
437 the element is read as described below. It is an error to take the
438 address of a subscript expression, or (in C++) to bind a reference to
441 Programs can use object subscripting with Objective-C object pointers of
442 type ``id``. Normal dynamic message send rules apply; the compiler must
443 see *some* declaration of the subscripting methods, and will pick the
444 declaration seen first.
449 Objects created using the literal or boxed expression syntax are not
450 guaranteed to be uniqued by the runtime, but nor are they guaranteed to
451 be newly-allocated. As such, the result of performing direct comparisons
452 against the location of an object literal (using ``==``, ``!=``, ``<``,
453 ``<=``, ``>``, or ``>=``) is not well-defined. This is usually a simple
454 mistake in code that intended to call the ``isEqual:`` method (or the
455 ``compare:`` method).
457 This caveat applies to compile-time string literals as well.
458 Historically, string literals (using the ``@"..."`` syntax) have been
459 uniqued across translation units during linking. This is an
460 implementation detail of the compiler and should not be relied upon. If
461 you are using such code, please use global string constants instead
462 (``NSString * const MyConst = @"..."``) or use ``isEqual:``.
467 To support the new syntax described above, the Objective-C
468 ``@``-expression grammar has the following new productions:
472 objc-at-expression : '@' (string-literal | encode-literal | selector-literal | protocol-literal | object-literal)
475 object-literal : ('+' | '-')? numeric-constant
482 boolean-constant : '__objc_yes' | '__objc_no' | 'true' | 'false' /* boolean keywords. */
485 array-literal : '[' assignment-expression-list ']'
488 assignment-expression-list : assignment-expression (',' assignment-expression-list)?
492 dictionary-literal : '{' key-value-list '}'
495 key-value-list : key-value-pair (',' key-value-list)?
499 key-value-pair : assignment-expression ':' assignment-expression
502 Note: ``@true`` and ``@false`` are only supported in Objective-C++.
507 Programs test for the new features by using clang's \_\_has\_feature
508 checks. Here are examples of their use:
512 #if __has_feature(objc_array_literals)
514 NSArray *elements = @[ @"H", @"He", @"O", @"C" ];
516 // old way (equivalent).
517 id objects[] = { @"H", @"He", @"O", @"C" };
518 NSArray *elements = [NSArray arrayWithObjects:objects count:4];
521 #if __has_feature(objc_dictionary_literals)
523 NSDictionary *masses = @{ @"H" : @1.0078, @"He" : @4.0026, @"O" : @15.9990, @"C" : @12.0096 };
525 // old way (equivalent).
526 id keys[] = { @"H", @"He", @"O", @"C" };
527 id values[] = { [NSNumber numberWithDouble:1.0078], [NSNumber numberWithDouble:4.0026],
528 [NSNumber numberWithDouble:15.9990], [NSNumber numberWithDouble:12.0096] };
529 NSDictionary *masses = [NSDictionary dictionaryWithObjects:objects forKeys:keys count:4];
532 #if __has_feature(objc_subscripting)
533 NSUInteger i, count = elements.count;
534 for (i = 0; i < count; ++i) {
535 NSString *element = elements[i];
536 NSNumber *mass = masses[element];
537 NSLog(@"the mass of %@ is %@", element, mass);
540 NSUInteger i, count = [elements count];
541 for (i = 0; i < count; ++i) {
542 NSString *element = [elements objectAtIndex:i];
543 NSNumber *mass = [masses objectForKey:element];
544 NSLog(@"the mass of %@ is %@", element, mass);
548 Code can use also ``__has_feature(objc_bool)`` to check for the
549 availability of numeric literals support. This checks for the new
550 ``__objc_yes / __objc_no`` keywords, which enable the use of
551 ``@YES / @NO`` literals.
553 To check whether boxed expressions are supported, use
554 ``__has_feature(objc_boxed_expressions)`` feature macro.