2016-03-18 35 views
1

我有一个关于const变量弱属性的问题。我有以下几个文件,用gcc编译:常量变量的GCC弱属性

的main.c:

#include <stdio.h> 

const int my_var __attribute__((weak)) = 100; 

int 
main(int argc, char *argv[]) 
{ 
    printf("my_var = %d\n", my_var); 
} 

other.c:

const int my_var = 200; 

当我编译这两个文件并运行应用程序我得到的结果如下:由于我在main.c中使用弱属性上my_var变量

my_var = 100 

我寿ught应该由my_var变量other.c被覆盖,但事实并非如此......

现在,如果我在main.c下降的my_varconst关键字:

#include <stdio.h> 
/* Dropping const... */ 
int my_var __attribute__((weak)) = 100; 

int 
main(int argc, char *argv[]) 
{ 
    printf("my_var = %d\n", my_var); 
} 

然后重新编译,我得到想要的结果:

my_var = 200 

这是我所期望的。

注意:为什么使用const关键字改变weak属性的行为:如果我的文件other.c中删除const我仍然得到的200

我的问题是,结果呢?它与变量驻留在哪一部分有关?

我使用的Makefile文件是:

.PHONY: all clean 

TARGET=test 
OBJS=main.o other.o 

all: $(TARGET) 

$(TARGET): $(OBJS) 
    gcc $(OBJS) -o $(TARGET) 

main.o:main.c 
    gcc -c main.c 

other.o:other.c 
    gcc -c other.c 

clean: 
    rm -rf *.o $(TARGET) 

由于提前,

+0

AFAIK弱属性用于功能。 – LPs

+0

@LPs:它适用于两者。只有描述在函数属性中,var-attributes只是指tothat。 – Olaf

+1

您可能需要使用-fno-common编译才能正常工作。 – fuz

回答

0

标识符具有内部链接。这是一个过时的功能(应使用static存储类说明符)。在一般情况下,你应该有一个头与extern声明标识符:

extern const int my_var; 

不同预选赛链接是一个坏主意。

也许更好的理解方法是使用wekrefalias

+0

你对头文件是正确的,我没有把它添加到我在这里写的例子,但是,它并没有改变现象:使用'const'就像取消弱属性一样。 我的问题是:为什么当我放弃'const'限定符它按预期工作? 另一个问题:当你说这是一个笨拙的功能时,你是否提到弱变量? 谢谢 – user6083108

+0

@ user6083108:C标准甚至没有提及'__attribute__',甚至更不“弱”。请注意,gcc的'weak'属性实际上是指为变量生成的**符号**(即链接器/汇编语言,而不是C)。 C变量具有类型等附加属性。 “weak”属性实际上为符号添加了低于C语言的属性。没有冒犯性,但我可以推荐对这个(相当复杂的)主题做更多的研究吗?也许你真的使用'weakref'更好。对我而言,这比“弱”在全球范围内的作用更明确。 – Olaf

+0

陈旧过时:在这种情况下,我没有提到“弱”。 – Olaf