变量的外部和静态链接的奇怪行为

时间:2016-02-06 22:38:23

标签: c static linker external symbols

我发现dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{ NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *filename = [[NSUserDefaults standardUserDefaults] objectForKey:@"SavedArrayPath"]; NSString *path = [[paths objectAtIndex:0] stringByAppendingPathComponent:filename]; NSMutableArray *savedArray = [NSMutableArray arrayWithContentsOfFile:path]; dispatch_sync(dispatch_get_main_queue(), ^{ NSLog(@"SAVED ARRAY:%@",savedArray); }); }); extern(内部)变量的一些行为让我觉得很奇怪。

以下是一个例子:

static

-

/* file a.c */
#include <stdio.h>

/* variable with static linkage */
static int x = 24;

int f() {
        /* variable with extern linkage */
        extern int x; 
        return x;
}

int main() {
        printf("%d\n", f());
        return 0;
}

我使用以下方法编译此程序:

/* file x.c */
/* define symbol `x` to be an `int` equal to 100 */
int x = 100;

然后我运行我的程序并获得此输出:

$ cc a.c x.c -o a

为什么此程序会输出$ ./a 24 而不是24

1 个答案:

答案 0 :(得分:4)

引自link

  

下表列出了分配给在单个翻译单元中声明两次的对象的链接。该列指定第一个声明,行指定重新声明。

     

Table to resolve conflicting linkages

同样来自标准6.2.2节:

  

对于在该标识符的先前声明可见的范围内使用存储类说明符extern声明的标识符,如果先前声明指定内部或外部链接,则后面声明中的标识符的链接是相同的作为先前声明中指定的联系。如果没有先前声明可见,或者先前声明未指定链接,则标识符具有外部链接。

因此,文件a.c在内部解析了所有外部链接。 您的代码首先将x定义为静态,然后在翻译单元a.c中将其定义为外部。因此,链接在上表中是内部的。所以它会打印24