条件编译 Conditional Compilation

通常,Objective-C 程序的编译从源代码到可执行文件分为三个阶段。第一阶段,预处理程序(preprocessor)的工具扫描开发人员编写的代码,并转换为对编译器友好的格式;第二阶段,编译器从预处理的源代码生成目标代码(通常文件扩展名为 .o 格式);最后一个阶段,链接器(linker)将所有目标代码模块和库放在一起,解析符号链接(symbol reference)并创建可执行二进制文件(executable binary)。

预处理阶段会搜索开发人员编写的特殊指令(directive),并将其转换为编译器可以处理的代码。每个指令均以 # 开头,用于简化编程任务,并使代码易于阅读和管理。在这篇文章中,将介绍条件编译(conditional compilation)指令。

六个指令可用于控制条件编译。条件编译用于分割仅在满足指定条件时才编译指定程序块,程序块的文本是任意的,并且可以包含预处理程序指令、C 语句等。这些指令可以嵌套使用。条件编译的开头由以下三个指令之一标记:

  • #if
  • #ifdef
  • #ifndef

另外,可选使用下面两个指令之一来放置备用文本块:

  • #else
  • #elif

条件编译的末尾最终由下面命令标记:

  • #endif

如果#if#ifdef#ifndef条件为真(非0),则忽略#else#elif#endif指令(如果存在)之间的所有行。

如果#if#ifdef#ifndef条件为假(0),则忽略#if#ifdef#ifndef#else#elif#endif之间的所有行。

#if

#if指令语法如下:

#if constant-expression newline

该指令检查 constant-expression 是否为 true,操作数必须是一个整数表达式,不包含增量(++)、减量(--)、sizeof、指针、地址和强制转换符。

常量表达式中的标志符可以是宏、也可以不是宏,但不能是关键字、枚举常量等。常量表达式还可以包括已定义的预处理运算符。

#if中的常量表达式实质为文本替换,并且可以包含之前使用#define指令定义的标志符。替换发生在验证表达式之前,替换之后每个预处理都依照令牌词汇形式出现。

如果你对#define指令不熟悉,可以查看我的另一篇文章:宏(#define)与常量(const)的使用

如果使用未定义标志符,则编译器会将其视为常量零。

#ifdef

#ifdef指令语法如下:

#ifdef identifier newline

该指令检查 identifier 是否已定义。可以通过#define命令或命令行定义 identifier,如果该 identifier 稍后未被取消定义(使用#undef命令可以取消已定义的宏),则认为已定义。

#ifndef

#ifndef指令语法如下:

#ifndef identifier newline

该指令检查 identifier 是否未定义。

#else

#else指令语法如下:

#else newline

#if#ifdef#ifndef指令验证为 false 时,则#else指令界定要编译的可选文本。#else指令是可选的。

#elif

#elif指令语法如下:

#elif constant-expression newline

#elif指令执行的任务类似于 else if 语句。当#if#ifdef#ifndef为 false,且#elif为 true 时,编译#elif后的代码。#elif指令是可选的。

#endif

#endif指令语法如下:

#endif newline

#endif指令终止#if#ifdef#ifndef#else#elif指令的范围。

#endif指令数量根据使用的#elif#else而变化。下面两个实例等效:

#if false
.
.
#elif true
.
.
#endif

// 等效于

#if false
.
.
#else
#if true
.
.
#endif
#endif

defined 操作符

另一种验证宏是否已定义的方法是使用defined一元操作符。defined操作符有以下两种格式:

defined name
defined (name)

如果name已定义,则表达式结果为1,否则为0。

defined运算符对于使用#if指令检查多个宏特别有用。这样可以在一行检查多个宏是否定义,而不必使用多个#ifdef#ifndef指令。

#ifdef macro1
    NSLog(@"Hello!\n");
#endif
    
#ifndef macro2
    NSLog(@"Hello!\n");
#endif
    
#ifdef macro3
    NSLog(@"Hello!\n");
#endif

使用defined运算符则可以在单个#if指令中执行类似宏检查:

#if defined (macro1) || !defined (macro2) || defined (macro3)
    print("Hello!\n")
#endif

defined指令可以和任意逻辑运算符组合使用,但defined指令只能用在#if#elif指令的表达式中。

#import也是预处理指令。

如果一个 project 包含多个 target,想要通过预处理程序进行区分,则可以选中 target,修改 Build Settings 中 Preprocessing Macros 实现。如下所示:

processor.png

参考资料:

  1. Conditional Compilation (#if, #ifdef, #ifndef, #else, #elif, #endif, and defined)
  2. Using Objective-C Preprocessor Directives
  3. How can I add an #ifdef DEBUG to Xcode?

欢迎更多指正:https://github.com/pro648/tips/wiki

本文地址:https://github.com/pro648/tips/wiki/%E6%9D%A1%E4%BB%B6%E7%BC%96%E8%AF%91-Conditional-Compilation

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,425评论 4 361
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,058评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,186评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,848评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,249评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,554评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,830评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,536评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,239评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,505评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,004评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,346评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,999评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,060评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,821评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,574评论 2 271
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,480评论 2 267

推荐阅读更多精彩内容

  • 小说里的人,不奇传不成,一奇就演出各种匪夷所思的事情,却全是真人真事。这小段是《俗世奇人》封面上的,也是吸引...
    1704徐岳平阅读 1,055评论 0 0
  • 文丨《Dr.魏的家庭教育宝典》-宽容孩子的“磨蹭” 见: 身为成年人,你觉得怎样做事才算不磨蹭?一般来说,你可能希...
    宸辰工坊阅读 318评论 0 1
  • 举世皆浊我独醒,谁将九歌付瑶琴。 离骚一曲魂何处,楚江渺渺应有恨。 蓬头稚子佩香囊,白发老叟酒一樽。 龙舟待发千舸...
    金指尖阅读 190评论 0 3
  • 原文链接 经过一年努力,总算进入了一家大公司。 2016 年初,刚来厦门的时候,只有半年的 Android 自学经...
    binwin20阅读 282评论 3 3
  • 因为昨晚享受到的快感,强打着让自己坚持打卡在这个平台留下更多自己的文字。曾经喜欢手写日记,但是唯一的读者是自己,现...
    小纠结的坑坑阅读 221评论 0 0