什么时候gcc在编译时评估函数?

时间:2014-11-28 18:49:58

标签: c gcc

当我有以下代码时

int main(void) {
        printf("%zd\n", strlen("Hello World!"));

        return 0;
}

并使用-O3进行编译,strings将显示字符串“Hello World!”二进制文件中缺少它,因为它在编译时得到了评估。

如果我改为使用我自己的功能

static inline size_t my_strlen(const char *s) {
        const char *tmp = s;

        while (*++tmp);

        return tmp - s;
}

int main(void) {
        printf("%zd\n", my_strlen("Hello World!"));

        return 0;
}

使用相同的选项,仍然可以在二进制文件中找到该字符串。

为什么会这样?

2 个答案:

答案 0 :(得分:4)

因为它是标准允许的optimization

在某些系统上,strlen最终扩展为_builtin_strlen,这是GCC编译器所知道的。在我的计算机上/usr/include/x86_64-linux-gnu/bits/string.h<string.h>包含间接

# define strlen(str) \
  (__extension__ (__builtin_constant_p (str)         \
                 ? __builtin_strlen (str)            \
                 : __strlen_g (str)))

实际上它是由GNU glibcgcc

的混合完成的

答案 1 :(得分:2)

GCC可能在某处使用该字符串的长度替换常量字符串的strlen()。

使用自己的功能时,无法启用此优化。 GCC不知道my_strlen是否有副作用,因此每次都必须运行它。