xref: /minix3/external/bsd/llvm/dist/clang/docs/ObjectiveCLiterals.rst (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
1f4a2713aSLionel Sambuc====================
2f4a2713aSLionel SambucObjective-C Literals
3f4a2713aSLionel Sambuc====================
4f4a2713aSLionel Sambuc
5f4a2713aSLionel SambucIntroduction
6f4a2713aSLionel Sambuc============
7f4a2713aSLionel Sambuc
8f4a2713aSLionel SambucThree new features were introduced into clang at the same time:
9f4a2713aSLionel Sambuc*NSNumber Literals* provide a syntax for creating ``NSNumber`` from
10f4a2713aSLionel Sambucscalar literal expressions; *Collection Literals* provide a short-hand
11f4a2713aSLionel Sambucfor creating arrays and dictionaries; *Object Subscripting* provides a
12f4a2713aSLionel Sambucway to use subscripting with Objective-C objects. Users of Apple
13f4a2713aSLionel Sambuccompiler releases can use these features starting with the Apple LLVM
14f4a2713aSLionel SambucCompiler 4.0. Users of open-source LLVM.org compiler releases can use
15f4a2713aSLionel Sambucthese features starting with clang v3.1.
16f4a2713aSLionel Sambuc
17f4a2713aSLionel SambucThese language additions simplify common Objective-C programming
18f4a2713aSLionel Sambucpatterns, make programs more concise, and improve the safety of
19f4a2713aSLionel Sambuccontainer creation.
20f4a2713aSLionel Sambuc
21f4a2713aSLionel SambucThis document describes how the features are implemented in clang, and
22f4a2713aSLionel Sambuchow to use them in your own programs.
23f4a2713aSLionel Sambuc
24f4a2713aSLionel SambucNSNumber Literals
25f4a2713aSLionel Sambuc=================
26f4a2713aSLionel Sambuc
27f4a2713aSLionel SambucThe framework class ``NSNumber`` is used to wrap scalar values inside
28f4a2713aSLionel Sambucobjects: signed and unsigned integers (``char``, ``short``, ``int``,
29f4a2713aSLionel Sambuc``long``, ``long long``), floating point numbers (``float``,
30f4a2713aSLionel Sambuc``double``), and boolean values (``BOOL``, C++ ``bool``). Scalar values
31f4a2713aSLionel Sambucwrapped in objects are also known as *boxed* values.
32f4a2713aSLionel Sambuc
33f4a2713aSLionel SambucIn Objective-C, any character, numeric or boolean literal prefixed with
34f4a2713aSLionel Sambucthe ``'@'`` character will evaluate to a pointer to an ``NSNumber``
35f4a2713aSLionel Sambucobject initialized with that value. C's type suffixes may be used to
36f4a2713aSLionel Sambuccontrol the size of numeric literals.
37f4a2713aSLionel Sambuc
38f4a2713aSLionel SambucExamples
39f4a2713aSLionel Sambuc--------
40f4a2713aSLionel Sambuc
41f4a2713aSLionel SambucThe following program illustrates the rules for ``NSNumber`` literals:
42f4a2713aSLionel Sambuc
43f4a2713aSLionel Sambuc.. code-block:: objc
44f4a2713aSLionel Sambuc
45f4a2713aSLionel Sambuc    void main(int argc, const char *argv[]) {
46f4a2713aSLionel Sambuc      // character literals.
47f4a2713aSLionel Sambuc      NSNumber *theLetterZ = @'Z';          // equivalent to [NSNumber numberWithChar:'Z']
48f4a2713aSLionel Sambuc
49f4a2713aSLionel Sambuc      // integral literals.
50f4a2713aSLionel Sambuc      NSNumber *fortyTwo = @42;             // equivalent to [NSNumber numberWithInt:42]
51f4a2713aSLionel Sambuc      NSNumber *fortyTwoUnsigned = @42U;    // equivalent to [NSNumber numberWithUnsignedInt:42U]
52f4a2713aSLionel Sambuc      NSNumber *fortyTwoLong = @42L;        // equivalent to [NSNumber numberWithLong:42L]
53f4a2713aSLionel Sambuc      NSNumber *fortyTwoLongLong = @42LL;   // equivalent to [NSNumber numberWithLongLong:42LL]
54f4a2713aSLionel Sambuc
55f4a2713aSLionel Sambuc      // floating point literals.
56f4a2713aSLionel Sambuc      NSNumber *piFloat = @3.141592654F;    // equivalent to [NSNumber numberWithFloat:3.141592654F]
57f4a2713aSLionel Sambuc      NSNumber *piDouble = @3.1415926535;   // equivalent to [NSNumber numberWithDouble:3.1415926535]
58f4a2713aSLionel Sambuc
59f4a2713aSLionel Sambuc      // BOOL literals.
60f4a2713aSLionel Sambuc      NSNumber *yesNumber = @YES;           // equivalent to [NSNumber numberWithBool:YES]
61f4a2713aSLionel Sambuc      NSNumber *noNumber = @NO;             // equivalent to [NSNumber numberWithBool:NO]
62f4a2713aSLionel Sambuc
63f4a2713aSLionel Sambuc    #ifdef __cplusplus
64f4a2713aSLionel Sambuc      NSNumber *trueNumber = @true;         // equivalent to [NSNumber numberWithBool:(BOOL)true]
65f4a2713aSLionel Sambuc      NSNumber *falseNumber = @false;       // equivalent to [NSNumber numberWithBool:(BOOL)false]
66f4a2713aSLionel Sambuc    #endif
67f4a2713aSLionel Sambuc    }
68f4a2713aSLionel Sambuc
69f4a2713aSLionel SambucDiscussion
70f4a2713aSLionel Sambuc----------
71f4a2713aSLionel Sambuc
72f4a2713aSLionel SambucNSNumber literals only support literal scalar values after the ``'@'``.
73f4a2713aSLionel SambucConsequently, ``@INT_MAX`` works, but ``@INT_MIN`` does not, because
74f4a2713aSLionel Sambucthey are defined like this:
75f4a2713aSLionel Sambuc
76f4a2713aSLionel Sambuc.. code-block:: objc
77f4a2713aSLionel Sambuc
78f4a2713aSLionel Sambuc    #define INT_MAX   2147483647  /* max value for an int */
79f4a2713aSLionel Sambuc    #define INT_MIN   (-2147483647-1) /* min value for an int */
80f4a2713aSLionel Sambuc
81f4a2713aSLionel SambucThe definition of ``INT_MIN`` is not a simple literal, but a
82f4a2713aSLionel Sambucparenthesized expression. Parenthesized expressions are supported using
83f4a2713aSLionel Sambucthe `boxed expression <#objc_boxed_expressions>`_ syntax, which is
84f4a2713aSLionel Sambucdescribed in the next section.
85f4a2713aSLionel Sambuc
86f4a2713aSLionel SambucBecause ``NSNumber`` does not currently support wrapping ``long double``
87f4a2713aSLionel Sambucvalues, the use of a ``long double NSNumber`` literal (e.g.
88f4a2713aSLionel Sambuc``@123.23L``) will be rejected by the compiler.
89f4a2713aSLionel Sambuc
90f4a2713aSLionel SambucPreviously, the ``BOOL`` type was simply a typedef for ``signed char``,
91f4a2713aSLionel Sambucand ``YES`` and ``NO`` were macros that expand to ``(BOOL)1`` and
92f4a2713aSLionel Sambuc``(BOOL)0`` respectively. To support ``@YES`` and ``@NO`` expressions,
93f4a2713aSLionel Sambucthese macros are now defined using new language keywords in
94*0a6a1f1dSLionel Sambuc``<objc/objc.h>``:
95f4a2713aSLionel Sambuc
96f4a2713aSLionel Sambuc.. code-block:: objc
97f4a2713aSLionel Sambuc
98f4a2713aSLionel Sambuc    #if __has_feature(objc_bool)
99f4a2713aSLionel Sambuc    #define YES             __objc_yes
100f4a2713aSLionel Sambuc    #define NO              __objc_no
101f4a2713aSLionel Sambuc    #else
102f4a2713aSLionel Sambuc    #define YES             ((BOOL)1)
103f4a2713aSLionel Sambuc    #define NO              ((BOOL)0)
104f4a2713aSLionel Sambuc    #endif
105f4a2713aSLionel Sambuc
106f4a2713aSLionel SambucThe compiler implicitly converts ``__objc_yes`` and ``__objc_no`` to
107f4a2713aSLionel Sambuc``(BOOL)1`` and ``(BOOL)0``. The keywords are used to disambiguate
108f4a2713aSLionel Sambuc``BOOL`` and integer literals.
109f4a2713aSLionel Sambuc
110f4a2713aSLionel SambucObjective-C++ also supports ``@true`` and ``@false`` expressions, which
111f4a2713aSLionel Sambucare equivalent to ``@YES`` and ``@NO``.
112f4a2713aSLionel Sambuc
113f4a2713aSLionel SambucBoxed Expressions
114f4a2713aSLionel Sambuc=================
115f4a2713aSLionel Sambuc
116f4a2713aSLionel SambucObjective-C provides a new syntax for boxing C expressions:
117f4a2713aSLionel Sambuc
118f4a2713aSLionel Sambuc.. code-block:: objc
119f4a2713aSLionel Sambuc
120f4a2713aSLionel Sambuc    @( <expression> )
121f4a2713aSLionel Sambuc
122f4a2713aSLionel SambucExpressions of scalar (numeric, enumerated, BOOL) and C string pointer
123f4a2713aSLionel Sambuctypes are supported:
124f4a2713aSLionel Sambuc
125f4a2713aSLionel Sambuc.. code-block:: objc
126f4a2713aSLionel Sambuc
127f4a2713aSLionel Sambuc    // numbers.
128f4a2713aSLionel Sambuc    NSNumber *smallestInt = @(-INT_MAX - 1);  // [NSNumber numberWithInt:(-INT_MAX - 1)]
129f4a2713aSLionel Sambuc    NSNumber *piOverTwo = @(M_PI / 2);        // [NSNumber numberWithDouble:(M_PI / 2)]
130f4a2713aSLionel Sambuc
131f4a2713aSLionel Sambuc    // enumerated types.
132f4a2713aSLionel Sambuc    typedef enum { Red, Green, Blue } Color;
133f4a2713aSLionel Sambuc    NSNumber *favoriteColor = @(Green);       // [NSNumber numberWithInt:((int)Green)]
134f4a2713aSLionel Sambuc
135f4a2713aSLionel Sambuc    // strings.
136f4a2713aSLionel Sambuc    NSString *path = @(getenv("PATH"));       // [NSString stringWithUTF8String:(getenv("PATH"))]
137f4a2713aSLionel Sambuc    NSArray *pathComponents = [path componentsSeparatedByString:@":"];
138f4a2713aSLionel Sambuc
139f4a2713aSLionel SambucBoxed Enums
140f4a2713aSLionel Sambuc-----------
141f4a2713aSLionel Sambuc
142f4a2713aSLionel SambucCocoa frameworks frequently define constant values using *enums.*
143f4a2713aSLionel SambucAlthough enum values are integral, they may not be used directly as
144f4a2713aSLionel Sambucboxed literals (this avoids conflicts with future ``'@'``-prefixed
145f4a2713aSLionel SambucObjective-C keywords). Instead, an enum value must be placed inside a
146f4a2713aSLionel Sambucboxed expression. The following example demonstrates configuring an
147f4a2713aSLionel Sambuc``AVAudioRecorder`` using a dictionary that contains a boxed enumeration
148f4a2713aSLionel Sambucvalue:
149f4a2713aSLionel Sambuc
150f4a2713aSLionel Sambuc.. code-block:: objc
151f4a2713aSLionel Sambuc
152f4a2713aSLionel Sambuc    enum {
153f4a2713aSLionel Sambuc      AVAudioQualityMin = 0,
154f4a2713aSLionel Sambuc      AVAudioQualityLow = 0x20,
155f4a2713aSLionel Sambuc      AVAudioQualityMedium = 0x40,
156f4a2713aSLionel Sambuc      AVAudioQualityHigh = 0x60,
157f4a2713aSLionel Sambuc      AVAudioQualityMax = 0x7F
158f4a2713aSLionel Sambuc    };
159f4a2713aSLionel Sambuc
160f4a2713aSLionel Sambuc    - (AVAudioRecorder *)recordToFile:(NSURL *)fileURL {
161f4a2713aSLionel Sambuc      NSDictionary *settings = @{ AVEncoderAudioQualityKey : @(AVAudioQualityMax) };
162f4a2713aSLionel Sambuc      return [[AVAudioRecorder alloc] initWithURL:fileURL settings:settings error:NULL];
163f4a2713aSLionel Sambuc    }
164f4a2713aSLionel Sambuc
165f4a2713aSLionel SambucThe expression ``@(AVAudioQualityMax)`` converts ``AVAudioQualityMax``
166f4a2713aSLionel Sambucto an integer type, and boxes the value accordingly. If the enum has a
167f4a2713aSLionel Sambuc:ref:`fixed underlying type <objc-fixed-enum>` as in:
168f4a2713aSLionel Sambuc
169f4a2713aSLionel Sambuc.. code-block:: objc
170f4a2713aSLionel Sambuc
171f4a2713aSLionel Sambuc    typedef enum : unsigned char { Red, Green, Blue } Color;
172f4a2713aSLionel Sambuc    NSNumber *red = @(Red), *green = @(Green), *blue = @(Blue); // => [NSNumber numberWithUnsignedChar:]
173f4a2713aSLionel Sambuc
174f4a2713aSLionel Sambucthen the fixed underlying type will be used to select the correct
175f4a2713aSLionel Sambuc``NSNumber`` creation method.
176f4a2713aSLionel Sambuc
177f4a2713aSLionel SambucBoxing a value of enum type will result in a ``NSNumber`` pointer with a
178f4a2713aSLionel Sambuccreation method according to the underlying type of the enum, which can
179f4a2713aSLionel Sambucbe a :ref:`fixed underlying type <objc-fixed-enum>`
180f4a2713aSLionel Sambucor a compiler-defined integer type capable of representing the values of
181f4a2713aSLionel Sambucall the members of the enumeration:
182f4a2713aSLionel Sambuc
183f4a2713aSLionel Sambuc.. code-block:: objc
184f4a2713aSLionel Sambuc
185f4a2713aSLionel Sambuc    typedef enum : unsigned char { Red, Green, Blue } Color;
186f4a2713aSLionel Sambuc    Color col = Red;
187f4a2713aSLionel Sambuc    NSNumber *nsCol = @(col); // => [NSNumber numberWithUnsignedChar:]
188f4a2713aSLionel Sambuc
189f4a2713aSLionel SambucBoxed C Strings
190f4a2713aSLionel Sambuc---------------
191f4a2713aSLionel Sambuc
192f4a2713aSLionel SambucA C string literal prefixed by the ``'@'`` token denotes an ``NSString``
193f4a2713aSLionel Sambucliteral in the same way a numeric literal prefixed by the ``'@'`` token
194f4a2713aSLionel Sambucdenotes an ``NSNumber`` literal. When the type of the parenthesized
195f4a2713aSLionel Sambucexpression is ``(char *)`` or ``(const char *)``, the result of the
196f4a2713aSLionel Sambucboxed expression is a pointer to an ``NSString`` object containing
197f4a2713aSLionel Sambucequivalent character data, which is assumed to be '\\0'-terminated and
198f4a2713aSLionel SambucUTF-8 encoded. The following example converts C-style command line
199f4a2713aSLionel Sambucarguments into ``NSString`` objects.
200f4a2713aSLionel Sambuc
201f4a2713aSLionel Sambuc.. code-block:: objc
202f4a2713aSLionel Sambuc
203f4a2713aSLionel Sambuc    // Partition command line arguments into positional and option arguments.
204f4a2713aSLionel Sambuc    NSMutableArray *args = [NSMutableArray new];
205f4a2713aSLionel Sambuc    NSMutableDictionary *options = [NSMutableDictionary new];
206f4a2713aSLionel Sambuc    while (--argc) {
207f4a2713aSLionel Sambuc        const char *arg = *++argv;
208f4a2713aSLionel Sambuc        if (strncmp(arg, "--", 2) == 0) {
209f4a2713aSLionel Sambuc            options[@(arg + 2)] = @(*++argv);   // --key value
210f4a2713aSLionel Sambuc        } else {
211f4a2713aSLionel Sambuc            [args addObject:@(arg)];            // positional argument
212f4a2713aSLionel Sambuc        }
213f4a2713aSLionel Sambuc    }
214f4a2713aSLionel Sambuc
215f4a2713aSLionel SambucAs with all C pointers, character pointer expressions can involve
216f4a2713aSLionel Sambucarbitrary pointer arithmetic, therefore programmers must ensure that the
217f4a2713aSLionel Sambuccharacter data is valid. Passing ``NULL`` as the character pointer will
218f4a2713aSLionel Sambucraise an exception at runtime. When possible, the compiler will reject
219f4a2713aSLionel Sambuc``NULL`` character pointers used in boxed expressions.
220f4a2713aSLionel Sambuc
221f4a2713aSLionel SambucContainer Literals
222f4a2713aSLionel Sambuc==================
223f4a2713aSLionel Sambuc
224f4a2713aSLionel SambucObjective-C now supports a new expression syntax for creating immutable
225f4a2713aSLionel Sambucarray and dictionary container objects.
226f4a2713aSLionel Sambuc
227f4a2713aSLionel SambucExamples
228f4a2713aSLionel Sambuc--------
229f4a2713aSLionel Sambuc
230f4a2713aSLionel SambucImmutable array expression:
231f4a2713aSLionel Sambuc
232f4a2713aSLionel Sambuc.. code-block:: objc
233f4a2713aSLionel Sambuc
234f4a2713aSLionel Sambuc    NSArray *array = @[ @"Hello", NSApp, [NSNumber numberWithInt:42] ];
235f4a2713aSLionel Sambuc
236f4a2713aSLionel SambucThis creates an ``NSArray`` with 3 elements. The comma-separated
237f4a2713aSLionel Sambucsub-expressions of an array literal can be any Objective-C object
238f4a2713aSLionel Sambucpointer typed expression.
239f4a2713aSLionel Sambuc
240f4a2713aSLionel SambucImmutable dictionary expression:
241f4a2713aSLionel Sambuc
242f4a2713aSLionel Sambuc.. code-block:: objc
243f4a2713aSLionel Sambuc
244f4a2713aSLionel Sambuc    NSDictionary *dictionary = @{
245f4a2713aSLionel Sambuc        @"name" : NSUserName(),
246f4a2713aSLionel Sambuc        @"date" : [NSDate date],
247f4a2713aSLionel Sambuc        @"processInfo" : [NSProcessInfo processInfo]
248f4a2713aSLionel Sambuc    };
249f4a2713aSLionel Sambuc
250f4a2713aSLionel SambucThis creates an ``NSDictionary`` with 3 key/value pairs. Value
251f4a2713aSLionel Sambucsub-expressions of a dictionary literal must be Objective-C object
252f4a2713aSLionel Sambucpointer typed, as in array literals. Key sub-expressions must be of an
253f4a2713aSLionel SambucObjective-C object pointer type that implements the
254*0a6a1f1dSLionel Sambuc``<NSCopying>`` protocol.
255f4a2713aSLionel Sambuc
256f4a2713aSLionel SambucDiscussion
257f4a2713aSLionel Sambuc----------
258f4a2713aSLionel Sambuc
259f4a2713aSLionel SambucNeither keys nor values can have the value ``nil`` in containers. If the
260f4a2713aSLionel Sambuccompiler can prove that a key or value is ``nil`` at compile time, then
261f4a2713aSLionel Sambuca warning will be emitted. Otherwise, a runtime error will occur.
262f4a2713aSLionel Sambuc
263f4a2713aSLionel SambucUsing array and dictionary literals is safer than the variadic creation
264f4a2713aSLionel Sambucforms commonly in use today. Array literal expressions expand to calls
265f4a2713aSLionel Sambucto ``+[NSArray arrayWithObjects:count:]``, which validates that all
266f4a2713aSLionel Sambucobjects are non-``nil``. The variadic form,
267f4a2713aSLionel Sambuc``+[NSArray arrayWithObjects:]`` uses ``nil`` as an argument list
268f4a2713aSLionel Sambucterminator, which can lead to malformed array objects. Dictionary
269f4a2713aSLionel Sambucliterals are similarly created with
270f4a2713aSLionel Sambuc``+[NSDictionary dictionaryWithObjects:forKeys:count:]`` which validates
271f4a2713aSLionel Sambucall objects and keys, unlike
272f4a2713aSLionel Sambuc``+[NSDictionary dictionaryWithObjectsAndKeys:]`` which also uses a
273f4a2713aSLionel Sambuc``nil`` parameter as an argument list terminator.
274f4a2713aSLionel Sambuc
275f4a2713aSLionel SambucObject Subscripting
276f4a2713aSLionel Sambuc===================
277f4a2713aSLionel Sambuc
278f4a2713aSLionel SambucObjective-C object pointer values can now be used with C's subscripting
279f4a2713aSLionel Sambucoperator.
280f4a2713aSLionel Sambuc
281f4a2713aSLionel SambucExamples
282f4a2713aSLionel Sambuc--------
283f4a2713aSLionel Sambuc
284f4a2713aSLionel SambucThe following code demonstrates the use of object subscripting syntax
285f4a2713aSLionel Sambucwith ``NSMutableArray`` and ``NSMutableDictionary`` objects:
286f4a2713aSLionel Sambuc
287f4a2713aSLionel Sambuc.. code-block:: objc
288f4a2713aSLionel Sambuc
289f4a2713aSLionel Sambuc    NSMutableArray *array = ...;
290f4a2713aSLionel Sambuc    NSUInteger idx = ...;
291f4a2713aSLionel Sambuc    id newObject = ...;
292f4a2713aSLionel Sambuc    id oldObject = array[idx];
293f4a2713aSLionel Sambuc    array[idx] = newObject;         // replace oldObject with newObject
294f4a2713aSLionel Sambuc
295f4a2713aSLionel Sambuc    NSMutableDictionary *dictionary = ...;
296f4a2713aSLionel Sambuc    NSString *key = ...;
297f4a2713aSLionel Sambuc    oldObject = dictionary[key];
298f4a2713aSLionel Sambuc    dictionary[key] = newObject;    // replace oldObject with newObject
299f4a2713aSLionel Sambuc
300f4a2713aSLionel SambucThe next section explains how subscripting expressions map to accessor
301f4a2713aSLionel Sambucmethods.
302f4a2713aSLionel Sambuc
303f4a2713aSLionel SambucSubscripting Methods
304f4a2713aSLionel Sambuc--------------------
305f4a2713aSLionel Sambuc
306f4a2713aSLionel SambucObjective-C supports two kinds of subscript expressions: *array-style*
307f4a2713aSLionel Sambucsubscript expressions use integer typed subscripts; *dictionary-style*
308f4a2713aSLionel Sambucsubscript expressions use Objective-C object pointer typed subscripts.
309f4a2713aSLionel SambucEach type of subscript expression is mapped to a message send using a
310f4a2713aSLionel Sambucpredefined selector. The advantage of this design is flexibility: class
311f4a2713aSLionel Sambucdesigners are free to introduce subscripting by declaring methods or by
312f4a2713aSLionel Sambucadopting protocols. Moreover, because the method names are selected by
313f4a2713aSLionel Sambucthe type of the subscript, an object can be subscripted using both array
314f4a2713aSLionel Sambucand dictionary styles.
315f4a2713aSLionel Sambuc
316f4a2713aSLionel SambucArray-Style Subscripting
317f4a2713aSLionel Sambuc^^^^^^^^^^^^^^^^^^^^^^^^
318f4a2713aSLionel Sambuc
319f4a2713aSLionel SambucWhen the subscript operand has an integral type, the expression is
320f4a2713aSLionel Sambucrewritten to use one of two different selectors, depending on whether
321f4a2713aSLionel Sambucthe element is being read or written. When an expression reads an
322f4a2713aSLionel Sambucelement using an integral index, as in the following example:
323f4a2713aSLionel Sambuc
324f4a2713aSLionel Sambuc.. code-block:: objc
325f4a2713aSLionel Sambuc
326f4a2713aSLionel Sambuc    NSUInteger idx = ...;
327f4a2713aSLionel Sambuc    id value = object[idx];
328f4a2713aSLionel Sambuc
329f4a2713aSLionel Sambucit is translated into a call to ``objectAtIndexedSubscript:``
330f4a2713aSLionel Sambuc
331f4a2713aSLionel Sambuc.. code-block:: objc
332f4a2713aSLionel Sambuc
333f4a2713aSLionel Sambuc    id value = [object objectAtIndexedSubscript:idx];
334f4a2713aSLionel Sambuc
335f4a2713aSLionel SambucWhen an expression writes an element using an integral index:
336f4a2713aSLionel Sambuc
337f4a2713aSLionel Sambuc.. code-block:: objc
338f4a2713aSLionel Sambuc
339f4a2713aSLionel Sambuc    object[idx] = newValue;
340f4a2713aSLionel Sambuc
341f4a2713aSLionel Sambucit is translated to a call to ``setObject:atIndexedSubscript:``
342f4a2713aSLionel Sambuc
343f4a2713aSLionel Sambuc.. code-block:: objc
344f4a2713aSLionel Sambuc
345f4a2713aSLionel Sambuc    [object setObject:newValue atIndexedSubscript:idx];
346f4a2713aSLionel Sambuc
347f4a2713aSLionel SambucThese message sends are then type-checked and performed just like
348f4a2713aSLionel Sambucexplicit message sends. The method used for objectAtIndexedSubscript:
349f4a2713aSLionel Sambucmust be declared with an argument of integral type and a return value of
350f4a2713aSLionel Sambucsome Objective-C object pointer type. The method used for
351f4a2713aSLionel SambucsetObject:atIndexedSubscript: must be declared with its first argument
352f4a2713aSLionel Sambuchaving some Objective-C pointer type and its second argument having
353f4a2713aSLionel Sambucintegral type.
354f4a2713aSLionel Sambuc
355f4a2713aSLionel SambucThe meaning of indexes is left up to the declaring class. The compiler
356f4a2713aSLionel Sambucwill coerce the index to the appropriate argument type of the method it
357f4a2713aSLionel Sambucuses for type-checking. For an instance of ``NSArray``, reading an
358f4a2713aSLionel Sambucelement using an index outside the range ``[0, array.count)`` will raise
359f4a2713aSLionel Sambucan exception. For an instance of ``NSMutableArray``, assigning to an
360f4a2713aSLionel Sambucelement using an index within this range will replace that element, but
361f4a2713aSLionel Sambucassigning to an element using an index outside this range will raise an
362f4a2713aSLionel Sambucexception; no syntax is provided for inserting, appending, or removing
363f4a2713aSLionel Sambucelements for mutable arrays.
364f4a2713aSLionel Sambuc
365f4a2713aSLionel SambucA class need not declare both methods in order to take advantage of this
366f4a2713aSLionel Sambuclanguage feature. For example, the class ``NSArray`` declares only
367f4a2713aSLionel Sambuc``objectAtIndexedSubscript:``, so that assignments to elements will fail
368f4a2713aSLionel Sambucto type-check; moreover, its subclass ``NSMutableArray`` declares
369f4a2713aSLionel Sambuc``setObject:atIndexedSubscript:``.
370f4a2713aSLionel Sambuc
371f4a2713aSLionel SambucDictionary-Style Subscripting
372f4a2713aSLionel Sambuc^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
373f4a2713aSLionel Sambuc
374f4a2713aSLionel SambucWhen the subscript operand has an Objective-C object pointer type, the
375f4a2713aSLionel Sambucexpression is rewritten to use one of two different selectors, depending
376f4a2713aSLionel Sambucon whether the element is being read from or written to. When an
377f4a2713aSLionel Sambucexpression reads an element using an Objective-C object pointer
378f4a2713aSLionel Sambucsubscript operand, as in the following example:
379f4a2713aSLionel Sambuc
380f4a2713aSLionel Sambuc.. code-block:: objc
381f4a2713aSLionel Sambuc
382f4a2713aSLionel Sambuc    id key = ...;
383f4a2713aSLionel Sambuc    id value = object[key];
384f4a2713aSLionel Sambuc
385f4a2713aSLionel Sambucit is translated into a call to the ``objectForKeyedSubscript:`` method:
386f4a2713aSLionel Sambuc
387f4a2713aSLionel Sambuc.. code-block:: objc
388f4a2713aSLionel Sambuc
389f4a2713aSLionel Sambuc    id value = [object objectForKeyedSubscript:key];
390f4a2713aSLionel Sambuc
391f4a2713aSLionel SambucWhen an expression writes an element using an Objective-C object pointer
392f4a2713aSLionel Sambucsubscript:
393f4a2713aSLionel Sambuc
394f4a2713aSLionel Sambuc.. code-block:: objc
395f4a2713aSLionel Sambuc
396f4a2713aSLionel Sambuc    object[key] = newValue;
397f4a2713aSLionel Sambuc
398f4a2713aSLionel Sambucit is translated to a call to ``setObject:forKeyedSubscript:``
399f4a2713aSLionel Sambuc
400f4a2713aSLionel Sambuc.. code-block:: objc
401f4a2713aSLionel Sambuc
402f4a2713aSLionel Sambuc    [object setObject:newValue forKeyedSubscript:key];
403f4a2713aSLionel Sambuc
404f4a2713aSLionel SambucThe behavior of ``setObject:forKeyedSubscript:`` is class-specific; but
405f4a2713aSLionel Sambucin general it should replace an existing value if one is already
406f4a2713aSLionel Sambucassociated with a key, otherwise it should add a new value for the key.
407f4a2713aSLionel SambucNo syntax is provided for removing elements from mutable dictionaries.
408f4a2713aSLionel Sambuc
409f4a2713aSLionel SambucDiscussion
410f4a2713aSLionel Sambuc----------
411f4a2713aSLionel Sambuc
412f4a2713aSLionel SambucAn Objective-C subscript expression occurs when the base operand of the
413f4a2713aSLionel SambucC subscript operator has an Objective-C object pointer type. Since this
414f4a2713aSLionel Sambucpotentially collides with pointer arithmetic on the value, these
415f4a2713aSLionel Sambucexpressions are only supported under the modern Objective-C runtime,
416f4a2713aSLionel Sambucwhich categorically forbids such arithmetic.
417f4a2713aSLionel Sambuc
418f4a2713aSLionel SambucCurrently, only subscripts of integral or Objective-C object pointer
419f4a2713aSLionel Sambuctype are supported. In C++, a class type can be used if it has a single
420f4a2713aSLionel Sambucconversion function to an integral or Objective-C pointer type, in which
421f4a2713aSLionel Sambuccase that conversion is applied and analysis continues as appropriate.
422f4a2713aSLionel SambucOtherwise, the expression is ill-formed.
423f4a2713aSLionel Sambuc
424f4a2713aSLionel SambucAn Objective-C object subscript expression is always an l-value. If the
425f4a2713aSLionel Sambucexpression appears on the left-hand side of a simple assignment operator
426f4a2713aSLionel Sambuc(=), the element is written as described below. If the expression
427f4a2713aSLionel Sambucappears on the left-hand side of a compound assignment operator (e.g.
428f4a2713aSLionel Sambuc+=), the program is ill-formed, because the result of reading an element
429f4a2713aSLionel Sambucis always an Objective-C object pointer and no binary operators are
430f4a2713aSLionel Sambuclegal on such pointers. If the expression appears in any other position,
431f4a2713aSLionel Sambucthe element is read as described below. It is an error to take the
432f4a2713aSLionel Sambucaddress of a subscript expression, or (in C++) to bind a reference to
433f4a2713aSLionel Sambucit.
434f4a2713aSLionel Sambuc
435f4a2713aSLionel SambucPrograms can use object subscripting with Objective-C object pointers of
436f4a2713aSLionel Sambuctype ``id``. Normal dynamic message send rules apply; the compiler must
437f4a2713aSLionel Sambucsee *some* declaration of the subscripting methods, and will pick the
438f4a2713aSLionel Sambucdeclaration seen first.
439f4a2713aSLionel Sambuc
440f4a2713aSLionel SambucCaveats
441f4a2713aSLionel Sambuc=======
442f4a2713aSLionel Sambuc
443f4a2713aSLionel SambucObjects created using the literal or boxed expression syntax are not
444f4a2713aSLionel Sambucguaranteed to be uniqued by the runtime, but nor are they guaranteed to
445f4a2713aSLionel Sambucbe newly-allocated. As such, the result of performing direct comparisons
446f4a2713aSLionel Sambucagainst the location of an object literal (using ``==``, ``!=``, ``<``,
447f4a2713aSLionel Sambuc``<=``, ``>``, or ``>=``) is not well-defined. This is usually a simple
448f4a2713aSLionel Sambucmistake in code that intended to call the ``isEqual:`` method (or the
449f4a2713aSLionel Sambuc``compare:`` method).
450f4a2713aSLionel Sambuc
451f4a2713aSLionel SambucThis caveat applies to compile-time string literals as well.
452f4a2713aSLionel SambucHistorically, string literals (using the ``@"..."`` syntax) have been
453f4a2713aSLionel Sambucuniqued across translation units during linking. This is an
454f4a2713aSLionel Sambucimplementation detail of the compiler and should not be relied upon. If
455f4a2713aSLionel Sambucyou are using such code, please use global string constants instead
456f4a2713aSLionel Sambuc(``NSString * const MyConst = @"..."``) or use ``isEqual:``.
457f4a2713aSLionel Sambuc
458f4a2713aSLionel SambucGrammar Additions
459f4a2713aSLionel Sambuc=================
460f4a2713aSLionel Sambuc
461f4a2713aSLionel SambucTo support the new syntax described above, the Objective-C
462f4a2713aSLionel Sambuc``@``-expression grammar has the following new productions:
463f4a2713aSLionel Sambuc
464f4a2713aSLionel Sambuc::
465f4a2713aSLionel Sambuc
466f4a2713aSLionel Sambuc    objc-at-expression : '@' (string-literal | encode-literal | selector-literal | protocol-literal | object-literal)
467f4a2713aSLionel Sambuc                       ;
468f4a2713aSLionel Sambuc
469f4a2713aSLionel Sambuc    object-literal : ('+' | '-')? numeric-constant
470f4a2713aSLionel Sambuc                   | character-constant
471f4a2713aSLionel Sambuc                   | boolean-constant
472f4a2713aSLionel Sambuc                   | array-literal
473f4a2713aSLionel Sambuc                   | dictionary-literal
474f4a2713aSLionel Sambuc                   ;
475f4a2713aSLionel Sambuc
476f4a2713aSLionel Sambuc    boolean-constant : '__objc_yes' | '__objc_no' | 'true' | 'false'  /* boolean keywords. */
477f4a2713aSLionel Sambuc                     ;
478f4a2713aSLionel Sambuc
479f4a2713aSLionel Sambuc    array-literal : '[' assignment-expression-list ']'
480f4a2713aSLionel Sambuc                  ;
481f4a2713aSLionel Sambuc
482f4a2713aSLionel Sambuc    assignment-expression-list : assignment-expression (',' assignment-expression-list)?
483f4a2713aSLionel Sambuc                               | /* empty */
484f4a2713aSLionel Sambuc                               ;
485f4a2713aSLionel Sambuc
486f4a2713aSLionel Sambuc    dictionary-literal : '{' key-value-list '}'
487f4a2713aSLionel Sambuc                       ;
488f4a2713aSLionel Sambuc
489f4a2713aSLionel Sambuc    key-value-list : key-value-pair (',' key-value-list)?
490f4a2713aSLionel Sambuc                   | /* empty */
491f4a2713aSLionel Sambuc                   ;
492f4a2713aSLionel Sambuc
493f4a2713aSLionel Sambuc    key-value-pair : assignment-expression ':' assignment-expression
494f4a2713aSLionel Sambuc                   ;
495f4a2713aSLionel Sambuc
496f4a2713aSLionel SambucNote: ``@true`` and ``@false`` are only supported in Objective-C++.
497f4a2713aSLionel Sambuc
498f4a2713aSLionel SambucAvailability Checks
499f4a2713aSLionel Sambuc===================
500f4a2713aSLionel Sambuc
501f4a2713aSLionel SambucPrograms test for the new features by using clang's \_\_has\_feature
502f4a2713aSLionel Sambucchecks. Here are examples of their use:
503f4a2713aSLionel Sambuc
504f4a2713aSLionel Sambuc.. code-block:: objc
505f4a2713aSLionel Sambuc
506f4a2713aSLionel Sambuc    #if __has_feature(objc_array_literals)
507f4a2713aSLionel Sambuc        // new way.
508f4a2713aSLionel Sambuc        NSArray *elements = @[ @"H", @"He", @"O", @"C" ];
509f4a2713aSLionel Sambuc    #else
510f4a2713aSLionel Sambuc        // old way (equivalent).
511f4a2713aSLionel Sambuc        id objects[] = { @"H", @"He", @"O", @"C" };
512f4a2713aSLionel Sambuc        NSArray *elements = [NSArray arrayWithObjects:objects count:4];
513f4a2713aSLionel Sambuc    #endif
514f4a2713aSLionel Sambuc
515f4a2713aSLionel Sambuc    #if __has_feature(objc_dictionary_literals)
516f4a2713aSLionel Sambuc        // new way.
517f4a2713aSLionel Sambuc        NSDictionary *masses = @{ @"H" : @1.0078,  @"He" : @4.0026, @"O" : @15.9990, @"C" : @12.0096 };
518f4a2713aSLionel Sambuc    #else
519f4a2713aSLionel Sambuc        // old way (equivalent).
520f4a2713aSLionel Sambuc        id keys[] = { @"H", @"He", @"O", @"C" };
521f4a2713aSLionel Sambuc        id values[] = { [NSNumber numberWithDouble:1.0078], [NSNumber numberWithDouble:4.0026],
522f4a2713aSLionel Sambuc                        [NSNumber numberWithDouble:15.9990], [NSNumber numberWithDouble:12.0096] };
523f4a2713aSLionel Sambuc        NSDictionary *masses = [NSDictionary dictionaryWithObjects:objects forKeys:keys count:4];
524f4a2713aSLionel Sambuc    #endif
525f4a2713aSLionel Sambuc
526f4a2713aSLionel Sambuc    #if __has_feature(objc_subscripting)
527f4a2713aSLionel Sambuc        NSUInteger i, count = elements.count;
528f4a2713aSLionel Sambuc        for (i = 0; i < count; ++i) {
529f4a2713aSLionel Sambuc            NSString *element = elements[i];
530f4a2713aSLionel Sambuc            NSNumber *mass = masses[element];
531f4a2713aSLionel Sambuc            NSLog(@"the mass of %@ is %@", element, mass);
532f4a2713aSLionel Sambuc        }
533f4a2713aSLionel Sambuc    #else
534f4a2713aSLionel Sambuc        NSUInteger i, count = [elements count];
535f4a2713aSLionel Sambuc        for (i = 0; i < count; ++i) {
536f4a2713aSLionel Sambuc            NSString *element = [elements objectAtIndex:i];
537f4a2713aSLionel Sambuc            NSNumber *mass = [masses objectForKey:element];
538f4a2713aSLionel Sambuc            NSLog(@"the mass of %@ is %@", element, mass);
539f4a2713aSLionel Sambuc        }
540f4a2713aSLionel Sambuc    #endif
541f4a2713aSLionel Sambuc
542f4a2713aSLionel SambucCode can use also ``__has_feature(objc_bool)`` to check for the
543f4a2713aSLionel Sambucavailability of numeric literals support. This checks for the new
544f4a2713aSLionel Sambuc``__objc_yes / __objc_no`` keywords, which enable the use of
545f4a2713aSLionel Sambuc``@YES / @NO`` literals.
546f4a2713aSLionel Sambuc
547f4a2713aSLionel SambucTo check whether boxed expressions are supported, use
548f4a2713aSLionel Sambuc``__has_feature(objc_boxed_expressions)`` feature macro.
549