{"id":658,"date":"2010-07-19T23:56:19","date_gmt":"2010-07-20T04:56:19","guid":{"rendered":"http:\/\/vgable.com\/blog\/?p=658"},"modified":"2011-11-29T17:20:23","modified_gmt":"2011-11-29T22:20:23","slug":"define-string","status":"publish","type":"post","link":"https:\/\/vgable.com\/blog\/2010\/07\/19\/define-string\/","title":{"rendered":"#define String"},"content":{"rendered":"<p>When I need a string-constant, I <code>#define<\/code> it, instead of doing the &#8220;right&#8221; thing and using an <code>extern const NSString *<\/code> variable.<\/p>\n<p><H3>UPDATE 2010-07-20<\/H3> Thanks to <a href=\"http:\/\/twitter.com\/elfredpagan\">Elfred Pagen<\/a> for pointing out that you should <strong>always put () around your macros<\/strong>. Wrong: <del><code>#define A_STRING @\"hello\"<\/code><\/del><\/p>\n<p>instead use (), even when you don&#8217;t think you have to:<\/p>\n<p><code>#define A_STRING (@\"hello\")<\/code><\/p>\n<p>This prevents <strong>accidental string concatenation<\/strong>. In C, string-literals separated only by whitespace are implicitly concatenated. It&#8217;s the same with Objective-C string literals.  This feature lets you break long strings up into several lines, so <code>NSString *x = @\"A long string!\"<\/code> can be rewritten:<\/p>\n<div class=\"code-box\">\n<pre>\r\nNSString *x =\r\n\t@\"A long\"\r\n\t@\" string!\";\r\n<\/pre>\n<\/div>\n<p>Unfortunately, this seldom-used feature can backfire in unexpected ways. Consider making an array of two strings:<\/p>\n<div class=\"code-box\">\n<pre>\r\n#define X @\"ex\"\r\n#define P @\"plain\"\r\na = [NSArray arrayWithObjects:X\r\n                              P,\r\n                              nil];\r\n<\/pre>\n<\/div>\n<p>That <em>looks<\/em> right, but I forgot a &#8220;<code>,<\/code>&#8221; after <code>X<\/code>, so after string-concatenation, <code>a<\/code> is <code>['explain']<\/code>, not <code>['ex','plain']<\/code>.<\/p>\n<p>Moral of the story: <strong>you can never have too many ()&#8217;s in macros<\/strong>.<\/p>\n<p>And, now, back to why I use <code>#define<\/code>&#8230;<\/p>\n<h3>It&#8217;s less code<\/h3>\n<p>Using an <code>extern<\/code> variable means declaring it in a header, <em>and<\/em> defining it in some implementation file. But a macro is just one line in a header.<\/p>\n<h3>It&#8217;s faster to lookup<\/h3>\n<p>Because there&#8217;s only the definition of a macro, Open Quickly\/command-double-clicking a macro <em>always<\/em> jumps to the definition, so you can see what it&#8217;s value is in one step. Generally Xcode jumps to a symbol&#8217;s declaration first, and <em>then<\/em> it&#8217;s definition, making it slower to lookup the value of a <code>const<\/code> symbol.<\/p>\n<h3>It&#8217;s still type safe<\/h3>\n<p>An <code>@\"NSString literal\"<\/code> has type information, so mistakes like,<\/p>\n<pre>#define X (@\"immutable string\")\r\nNSMutableString *y = X;\r\n[y appendString:@\"z\"];\r\n<\/pre>\n<p>still generate warnings.<\/p>\n<h3>It lets the compiler <a href=\"http:\/\/bobthegnome.blogspot.com\/2009\/07\/format-not-string-literal-and-no-format.html\">check format-strings<\/a><\/h3>\n<p>Xcode can catch errors like &#8220;<code>[NSString stringWithFormat:@\"reading garbage since there's no argument: %s\"]<\/code>&#8220;, <a href=\"http:\/\/vgable.com\/blog\/2009\/12\/09\/compile-safer\/\">if you let it<\/a>. Unfortunately, the Objective-C compiler isn&#8217;t smart enough to check <code>[NSString stringWithFormat:externConstString,x,y,z];<\/code> because it doesn&#8217;t know what an <code>extern<\/code> variable contains until link-time. But preprocessor macros are evaluated early enough in the build process that that the compiler can check their values.<\/p>\n<h3>It can&#8217;t be changed at runtime<\/h3>\n<p>It&#8217;s possible to change the value of <code>const<\/code> variables through pointers, like so:<\/p>\n<div class=\"code-box\">\n<pre>\r\nconst NSString* const s = @\"initial\";\r\nNSString **hack = &s;\r\n*hack = @\"changed!\";\r\nNSLog(s);\/\/prints \"changed!\"\r\n<\/pre>\n<\/div>\n<p>Yes this is pathological code, but I&#8217;ve seen it happen (I&#8217;m looking at you <code>AddressBook.framework<\/code>!)<\/p>\n<p>Of course, you can re-<code>#define<\/code> a preprocessor-symbol, so macros aren&#8217;t a panacea for pathological constant-changing code. (Nothing is!) But they push the pathology into compile time, and common wisdom is that it&#8217;s easier to debug compile-time problems, so that&#8217;s a Good Thing. You may <a href=\"http:\/\/vgable.com\/blog\/2008\/09\/18\/i-would-rather-have-a-runtime-error-than-a-compile-error\/\">disagree there<\/a>, and you may be right! All I can say for sure is that <em>in my experience<\/em>, I&#8217;ve had bugs from <code>const<\/code> values changing at runtime, but no bugs from re-<code>#define<\/code>-ed constants (yet).<\/p>\n<h3>Conclusion<\/h3>\n<p>Preprocessor macros are damnably dangerous in C. Generally you should avoid them. But for <code>NSString*<\/code> constants in applications, I think they&#8217;re easier, and arguably less error prone. So go ahead and <code>#define YOUR_STRING_CONSTANTS (@\"like this\")<\/code>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>When I need a string-constant, I #define it, instead of doing the &#8220;right&#8221; thing and using an extern const NSString * variable. UPDATE 2010-07-20 Thanks to Elfred Pagen for pointing out that you should always put () around your macros. Wrong: #define A_STRING @&#8221;hello&#8221; instead use (), even when you don&#8217;t think you have to: [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[18,6,203,3,5,4],"tags":[241,613,607,80,78,242],"class_list":["post-658","post","type-post","status-publish","format-standard","hentry","category-bug-bite","category-cocoa","category-iphone","category-macosx","category-objective-c","category-programming","tag-best-practices","tag-c","tag-constants","tag-macros","tag-nsstring","tag-programming-style"],"_links":{"self":[{"href":"https:\/\/vgable.com\/blog\/wp-json\/wp\/v2\/posts\/658","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/vgable.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/vgable.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/vgable.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/vgable.com\/blog\/wp-json\/wp\/v2\/comments?post=658"}],"version-history":[{"count":4,"href":"https:\/\/vgable.com\/blog\/wp-json\/wp\/v2\/posts\/658\/revisions"}],"predecessor-version":[{"id":696,"href":"https:\/\/vgable.com\/blog\/wp-json\/wp\/v2\/posts\/658\/revisions\/696"}],"wp:attachment":[{"href":"https:\/\/vgable.com\/blog\/wp-json\/wp\/v2\/media?parent=658"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/vgable.com\/blog\/wp-json\/wp\/v2\/categories?post=658"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/vgable.com\/blog\/wp-json\/wp\/v2\/tags?post=658"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}