我正在使用不同的链接器脚本。在某些情况下,定义了一个值,在另一些情况下,则未定义该值:
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;
}
我第一个导致根据链接描述文件中该值的存在条件执行代码的弱属性:
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。
我很确定这个问题已经解决了,但我在网上找不到任何相关问题。
我的错误!
我尝试了很多组合,其实这个是错误的:
当我初始化弱符号时,有“半弱”
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));
未初始化的全局变量默认是弱的,所以你可以直接使用
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),但也许您的编译器以不同的方式处理这种不明确的情况。