在LJ post中,--defsym
标志用于将生成日期传递到源代码中:
#include <stdio.h>
extern char __BUILD_DATE;
void main(void) {
printf("Build date: %u\n", (unsigned long) &__BUILD_DATE);
}
通过链接以下标志:
gcc example.c -Xlinker --defsym -Xlinker __BUILD_DATE=$(date +%Y%m%d)
根据ld manual,
--defsym symbol=expression
在输出文件中创建一个全局符号,其中包含表达式给定的绝对地址。我试图理解以下内容:
构建日期(
YYYYmmdd
+\0
)的9个字符字符串如何存储在内存中?如果
--defsym
创建了一个包含地址的符号,为什么__BUILD_DATE
被定义为一个字符而不是指针或整数类型?为什么
__BUILD_DATE
被定义为char
而不是unsigned long
如果它最终被铸造成unsigned long
? 最佳答案
链接器将全局变量视为地址(指向“实际”全局而不是实际全局的指针),即使实际的全局不存在于该地址)。-Xlinker --defsym -Xlinker __BUILD_DATE=$(date +%Y%m%d)
设置地址而不是值。当of __BUILD_DATE
链接器实体有地址但没有值时,可以通过声明该实体为任意实体然后获取该实体的地址来获取地址。
在:
#include <stdio.h>
//extern long __BUILD_DATE[128];
//extern int __BUILD_DATE;
extern char __BUILD_DATE;
int main(void)
{
printf("Build date: %lu\n", (unsigned long)&__BUILD_DATE);
}
三个声明中的任何一个都应该有效。只是不要试图使用那个(伪)全局的值。这就像取消对无效指针的引用一样。
答案应该是2和3。要回答1,
__BUILD_DATE
将-Xlinker --defsym -Xlinker __BUILD_DATE=$(date +%Y%m%d)
返回的数字(stdout)存储为$(date %Y%m%d)
的地址。它不存储字符串。