我正在使用不同的链接描述文件。在某些情况下,定义了一个值,在其他情况下,它没有定义:
DIRECTORY_ADDRESS = 0x80100000;
DIRECTORY_SIZE = 32M;
在执行时,我希望在未定义此值时使用默认行为,并在定义此值时使用特殊行为。
经典地,我得到这样的值:
extern void * DIRECTORY_ADDRESS;
extern void * DIRECTORY_SIZE;
void f() {
void *dir_addr = &DIRECTORY_ADDRESS;
int dir_size = (int)&DIRECTORY_SIZE;
}
我根据链接器脚本中存在的这个值,第一次导致conditionnaly执行代码是弱引用:
extern void * DIRECTORY_ADDRESS __attribute__ ((weak)) = 0x0;
extern void * DIRECTORY_SIZE __attribute__ ((weak)) = 0x0;
void f() {
if ( DIRECTORY_ADDRESS )
// special code
else
// default code
}
但它无法工作,因为我正在初始化指针值,而不是它的地址:即使是一个未经解释的弱符号也有一个地址。所以目录地址总是!= NULL。
我很确定此问题已经解决,但我在网上找不到任何相关问题。
答案 0 :(得分:1)
我的错误!
我尝试了很多组合,这个实际上是错误的:
当我初始化弱符号时,有“半弱”
extern void * DIRECTORY_ADDRESS __attribute__ ((weak)) = 0x0;
extern void * DIRECTORY_SIZE __attribute__ ((weak)) = 0x0;
为了解决我的问题,我只需要让弱符号未初始化,如果它们没有用强符号定义,那么符号地址将为NULL:
extern void * DIRECTORY_ADDRESS __attribute__ ((weak));
extern void * DIRECTORY_SIZE __attribute__ ((weak));
答案 1 :(得分:1)
默认情况下,未初始化的全局变量很弱,因此您可以使用
void * DIRECTORY_ADDRESS;
void * DIRECTORY_SIZE;
如果没有为这些名称定义外部符号,则该值将默认为NULL。要强制使用不同于NULL的默认值,可以使用
void * DIRECTORY_ADDRESS __attribute__ ((weak)) = OTHER_VALUE;
void * DIRECTORY_SIZE __attribute__ ((weak)) = OTHER_VALUE;
请注意,初始化extern并不真正有意义:extern意味着定义在文件外部,但初始化提供了一个定义。我的编译器(gcc 4.4)警告用户这个,然后忽略extern修饰符。这意味着您的示例按预期工作(即使在初始化为0x0时),但也许您的编译器会以不同的方式处理这种不明确的情况。