<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Ahruman’s Webthing &#187; evil</title>
	<atom:link href="http://jens.ayton.se/blag/tag/evil/feed/" rel="self" type="application/rss+xml" />
	<link>http://jens.ayton.se/blag</link>
	<description>Cocoa coding stuff, when I can be bothered.</description>
	<lastBuildDate>Thu, 25 Aug 2011 21:56:35 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Constant objects for fun and non-profit</title>
		<link>http://jens.ayton.se/blag/objc-constant-objects/</link>
		<comments>http://jens.ayton.se/blag/objc-constant-objects/#comments</comments>
		<pubDate>Fri, 12 Dec 2008 02:27:05 +0000</pubDate>
		<dc:creator>Jens Ayton</dc:creator>
				<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[Code]]></category>
		<category><![CDATA[evil]]></category>

		<guid isPermaLink="false">http://jens.ayton.se/blag/?p=45</guid>
		<description><![CDATA[The @&#34;foo&#34; operator for constant NSString objects in Objective-C is extremely convenient. Indeed, if it wasn’t there, programming with Cocoa would be a royal pain. Many of us have at various points wished there was equivalent syntax for NSNumbers, and &#8230; <a href="http://jens.ayton.se/blag/objc-constant-objects/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>The <code>@&quot;foo&quot;</code> operator for constant <code>NSString</code> objects in Objective-C is extremely convenient. Indeed, if it wasn’t there, programming with Cocoa would be a royal pain. Many of us have at various points wished there was equivalent syntax for <code>NSNumber</code>s, and possibly collections.</p>
<p>As an early Christmas present to fellow lovers of twisted, evil code that should never have seen the light of day under any circumstances whatsoever, I hereby present an implementation of the first half of that wish.</p>
<p><span id="more-45"></span><br />
<h2>Caveat lector</h2>
<p>Now, when I say it’s evil, I really, really mean it. We’re talking about building objects in the data section of your code by packing structs, thus depending on data layout (and as such, depending on the old 32-bit runtime). We’re talking about nested macros with lots of <code>?:</code>s in them. We’re talking about gcc’s built-in parser pseudo-functions. Hearken to the words of Greg Parker, official Objective-C Runtime Wrangler at Apple:</p>
<p style="margin:0 3em">@<a href="https://twitter.com/gparker/status/1051085472">gparker</a>: @ahruman JANumberLiteral would break in several exciting ways in 64-bit. Might almost be safe enough in 32-bit, though.<br />
@<a href="https://twitter.com/ahruman/status/1051088370">ahruman</a>: @gparker Yeah, I know. I’ll be pasting “If you do this in real life, I’ll have to track you down and shoot you” warnings all over it. :-)<br />
@<a href="https://twitter.com/gparker/status/1052054292">gparker</a>: @ahruman Don&apos;t shoot &apos;em, just maim &apos;em a bit. I want my turn after you&apos;re done.<br />
@<a href="https://twitter.com/ahruman/status/1052079228">ahruman</a>: @gparker That’s what kneecaps were invented for.</p>
<p>Be told.</o></p>
<h2>Overview</h2>
<p>So, all that aside… what we’re looking at here is a macro <code>$N(n)</code> which takes a number and returns an <code>NSNumber</code>. (The convention of using dollar signs for macros implementing desired language features was introduced by <a href="http://mooseyard.com/Jens/">the other Jens A</a>.) If passed a compile-time constant, it will produce a constant object, i.e. a single, immortal instance based in the data section with no instantiation overhead, just like a string object constant. If passed a non-constant, it will give you a normal autoreleased <code>NSNumber</code> instead.</p>
<p>Constant <code>NSString</code>s work by creating a struct with the following layout: <code>{&nbsp;&amp;__CFConstantStringClassReference, 1992, &quot;foo&quot;, 3&nbsp;}</code>, where 1992 is a flag field and 3 is the length of the string. (Note that this is not the <code>NSConstantString</code> from the bottom of NSString.h. I believe this change was made in the OS X 10.2 SDK.) <code>__CFConstantStringClassReference</code> is a symbol exported from CoreFoundation.framework and implicitly declared in all Objective-C or Objective-C++ files by the compiler.<small><sup><a href="#objc-constant-objects-footnote-1" name="objc-constant-objects-footnote-ref-1">1</a></sup></small> My task, once I chose to accept it, was to do something similar for <code>NSNumber</code>.</p>
<p>Trying to build actual <code>NSCFNumber</code>s would be an unnecessary extra evil. Instead, I subclassed the abstract <code>NSNumber</code> twice, once for <code>long&nbsp;long</code>s and once for <code>double</code>s, giving me a known layout to target. The subclasses also override <code>-retain</code>, <code>-release</code> and <code>-autorelease</code> to do nothing, in the manner of a singleton. Then, building an instance is conceptually simple:</p>
<pre class="objc-code">const static struct { Class isa; double value; } fakeObj =
{ [JAFloatNumber class], 42.0 };
NSNumber *number = (NSNumber *)&fakeObj;</pre>
<p>The structure needs to be declared <code>static</code> so that it doesn’t evaporate at the end of the containing scope. This presents a dilemma, however: static initializers must be constant expressions, and a method call doesn’t qualify. Besides, we want the object to be constant data.</p>
<p>Luckily for us, classes are represented by global symbols like any other. Well, almost like any other. Unlike symbols based on C identifiers, their linker symbols don’t start with an underscore but with a dot, meaning you can’t reference them the usual way. Fortunately, gcc provides us with a solution in the form of <a href="http://gcc.gnu.org/onlinedocs/gcc-4.2.0/gcc/Asm-Labels.html">asm labels</a>:</p>
<pre class="objc-code">extern const struct objc_class JAFloatLiteralClassObject
        __asm__(&quot;.objc_class_name_JAFloatNumber&quot;);</pre>
<p>The basic implementation then becomes:</p>
<pre>#define JANUMBERLITERAL_CONSTANT_FLOAT(n) \
        ({ static const struct { const struct objc_class *isa; double value; } \
        object = { &#038;JAFloatLiteralClassObject, (n) }; \
        (NSNumber *)&object; })</pre>
<p>A problem here is that, despite all those <code>const</code>s, a non-const value can be used in Objective-C++. (In plain Objective-C, you get a moderately helpful warning about non-const initializers.) If you write a function that returns <code> JANUMBERLITERAL_CONSTANT_FLOAT(random());</code>, each instance will return the same object but its value will change, which is rather bad. The fix is to wrap this up in a macro that uses <code><a href="http://gcc.gnu.org/onlinedocs/gcc-4.2.0/gcc/Other-Builtins.html#index-g_t_005f_005fbuiltin_005fconstant_005fp-2458">__builtin_constant_p()</a></code> to ensure constant objects are only created with constant values. For non-constant values, normal autoreleased <code>NSNumber</code>s are created instead.</p>
<h2>Results</h2>
<p>The above pieces, along with a bunch of extra preprocessor stuff to handle the distinctions between Objective-C and Objective-C++ and between integer and floating point values gives us a <code>$N(n)</code> macro which works as advertised: if given an integer constant it returns a <code>JAIntegerNumber</code>, for a floating point constant it returns a <code>JAFloatNumber</code>, and for a non-constant it returns an autoreleased <code>NSCFNumber</code>. But is it really working as intended? The following code:</p>
<pre class="objc-code">static NSNumber *GetNumber(void)
{
    return $N(42.0);
}</pre>
<p>disassembles to:</p>
<pre class="asm-code">    .const_data
    .align 2
_object.67163:
    .long   .objc_class_name_JAFloatNumber  // isa
    .long   0           // low bytes of 42.0
    .long   1078263808  // high bytes of 42.0</pre>
<p>…with the actual use of the object inlined (in an optimized build) to <code>movl $_object.67163, (%esp)</code>. The values 0 and 1078263808 correspond to the little-endian hex value of 42.0: <code>00000000 00004540</code>. In other words, this really is an object as constant data. For comparison, the <code>NSString</code> literal used in the sample code disassembles to:</p>
<pre class="asm-code">    .cstring
LC0:
    .ascii &quot;Hello, World! %@ = %li (%@)\0&quot;
    .section __DATA, __cfstring
    .align 2
LC1:
    .long   ___CFConstantStringClassReference // isa
    .long   1992  // flags
    .long   LC0   // bytes pointer
    .long   27    // length</pre>
<h2>Conclusion</h2>
<p>So there you have it: fully-functional, constant <code>NSNumber</code> objects, as long as you don’t use the 64-bit runtime. Now don’t go actually using it, or I’ll have to shoot your kneecaps off and leave you to Greg.</p>
<p>Oh yeah, the code is <a href="http://code.google.com/p/ahruman/source/browse/#svn/trunk/Stupid/NumberLiteral">on Google Code</a>. For a much simpler macro that just gives you an <code>NSNumber</code>, automatically choosing between integer and floating-point representations, try <a href="http://www.extinguishedscholar.com/wpglob/?p=346">natevw’s</a>.</p>
<hr />
<p><small><sup><a href="#objc-constant-objects-footnote-ref-1" name="objc-constant-objects-footnote-1">^1</a></sup></small> Its value, on my system, is 0xa00034a0. Traditionally (pre Leopard), a value above 0xFFF would mean it’s a real Objective-C class rather than a CF type tag, but that test is no longer in the <a href="http://www.opensource.apple.com/darwinsource/10.5.5/CF-476.15/">CFLite source</a> in Leopard, so it may have changed.</p>
<p>If you declare <code>extern const Class __CFConstantStringClassReference;</code> in an Objective-C++ file, you’ll get the error “&apos;__CFConstantStringClassReference&apos; has a previous declaration as &apos;int __CFConstantStringClassReference []&apos;”. In Objective-C, you won’t be told a type, just that it was “previously declared here”, referring to the location “&lt;built-in>:0”.</p>
]]></content:encoded>
			<wfw:commentRss>http://jens.ayton.se/blag/objc-constant-objects/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>

