{"id":13351,"date":"2016-01-25T14:41:53","date_gmt":"2016-01-25T19:41:53","guid":{"rendered":"http:\/\/mjtsai.com\/blog\/?p=13351"},"modified":"2016-01-25T14:41:53","modified_gmt":"2016-01-25T19:41:53","slug":"7-scandalous-weird-old-things-about-the-c-preprocessor","status":"publish","type":"post","link":"https:\/\/mjtsai.com\/blog\/2016\/01\/25\/7-scandalous-weird-old-things-about-the-c-preprocessor\/","title":{"rendered":"7 Scandalous Weird Old Things About the C Preprocessor"},"content":{"rendered":"<p><a href=\"http:\/\/blog.robertelder.org\/7-weird-old-things-about-the-c-preprocessor\/\">Robert Elder<\/a> (via <a href=\"https:\/\/twitter.com\/steipete\/status\/690292664697253888\">Peter Steinberger<\/a>):<\/p>\n<blockquote cite=\"http:\/\/blog.robertelder.org\/7-weird-old-things-about-the-c-preprocessor\/\"><p>Bjarne Stroustrup even points out that the standard isn&rsquo;t clear about what should happen in function macro recursion[1].  With reference to a specific example he says &ldquo;The question is whether the use of NIL in the last line of this sequence qualifies for non-replacement under the cited text.  If it does, the result will be NIL(42). If it does not, the result will be simply 42.&rdquo;.  In 2004, a decision was made to leave the standard in its ambiguous state: &ldquo;The committee&rsquo;s decision was that no realistic programs &ldquo;in the wild&rdquo; would venture into this area, and trying to reduce the uncertainties is not worth the risk of changing conformance status of implementations or programs.&rdquo;<\/p><p>[&#8230;]<\/p><p>Many languages are first tokenized, and then the list of tokens doesn&rsquo;t change throughout further processing of the program.  In the C preprocessor, new tokens can be created at run time!  This makes it impossible to build a parse tree ahead of time because you don&rsquo;t know what tokens would be included in the final tree.<\/p><p>[&#8230;]<\/p><p>In general, when evaluating a function macro body, you need to consider both the pre-expanded version of the arguments, and the untouched tokens that were passed for that argument.  This behaviour is unlike how C arguments and functions are evaluated, because in C you can always replace an argument that&rsquo;s described by an expression with the result of that expression and have the same meaning (ignoring any side effects).<\/p><\/blockquote>\n<p>He also mentions handling of whitespace, which is confusing and also <a href=\"https:\/\/llvm.org\/bugs\/show_bug.cgi?id=12035\">buggy in Clang<\/a>.<\/p>","protected":false},"excerpt":{"rendered":"<p>Robert Elder (via Peter Steinberger): Bjarne Stroustrup even points out that the standard isn&rsquo;t clear about what should happen in function macro recursion[1]. With reference to a specific example he says &ldquo;The question is whether the use of NIL in the last line of this sequence qualifies for non-replacement under the cited text. If it [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"apple_news_api_created_at":"","apple_news_api_id":"","apple_news_api_modified_at":"","apple_news_api_revision":"","apple_news_api_share_url":"","apple_news_coverimage":0,"apple_news_coverimage_caption":"","apple_news_is_hidden":false,"apple_news_is_paid":false,"apple_news_is_preview":false,"apple_news_is_sponsored":false,"apple_news_maturity_rating":"","apple_news_metadata":"\"\"","apple_news_pullquote":"","apple_news_pullquote_position":"","apple_news_slug":"","apple_news_sections":"\"\"","apple_news_suppress_video_url":false,"apple_news_use_image_component":false,"footnotes":""},"categories":[4],"tags":[131,45,230,255,295,46,941,71],"class_list":["post-13351","post","type-post","status-publish","format-standard","hentry","category-programming-category","tag-bug","tag-c","tag-clang","tag-compiler","tag-history","tag-languagedesign","tag-macros","tag-programming"],"apple_news_notices":[],"_links":{"self":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts\/13351","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/comments?post=13351"}],"version-history":[{"count":1,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts\/13351\/revisions"}],"predecessor-version":[{"id":13352,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts\/13351\/revisions\/13352"}],"wp:attachment":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/media?parent=13351"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/categories?post=13351"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/tags?post=13351"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}