c++ - 编译器是否优化对常量变量的引用?

标签 c++ c performance optimization memory-management

当谈到 C 和 C++ 语言时,编译器是否优化了对常量变量的引用,以便程序自动知道所引用的值是什么,而不必查看常量变量的内存位置?说到数组,是否取决于数组中指向的索引值在编译时是否为常量?

例如,看一下这段代码:

int main(void) {
    1:  char tesst[3] = {'1', '3', '7'};
    2:  char erm = tesst[1];
}

编译器是否在编译时将第 2 行“更改”为“char erm = '3'”?

最佳答案

我个人希望发布的代码变成“无”,因为两个变量都没有实际使用,因此可以删除。

但是,是的,现代编译器(gcc、clang、msvc 等)应该能够用它的常量值替换对替代项的引用 [只要编译器可以合理地确定 testst< 的内容 没有被改变 - 如果你将 tests 传递给一个函数,即使它作为一个 const 引用,编译器实际上并不知道这个函数是不改变它,它会假定它会改变并加载值]。

使用 clang -O1 opts.c -S 编译:

#include <stdio.h>

int main()
{
    char tesst[3] = {'1', '3', '7'};
    char erm = tesst[1];

    printf("%d\n", erm);
}

产生:

...

main:
    pushq   %rax
.Ltmp0:
    movl    $.L.str, %edi
    movl    $51, %esi
    xorl    %eax, %eax
    callq   printf
    xorl    %eax, %eax
    popq    %rcx
    retq

 ...

因此,与 printf("%d\n", '3'); 相同。

[我使用的是 C 而不是 C++,因为如果我使用 cout,那将是大约 50 行汇编程序,因为所有内容都是内联的]

我希望 gcc 和 msvc 进行类似的优化(测试 gcc -O1 -S 并且它给出完全相同的代码,除了一些符号名称略有不同)

并说明“如果你调用一个函数,它可能不会这样做”:

#include <stdio.h>

extern void blah(const char* x);

int main()
{
    char tesst[3] = {'1', '3', '7'};
    blah(tesst);
    char erm = tesst[1];

    printf("%d\n", erm);
}


main:                                   # @main
    pushq   %rax
    movb    $55, 6(%rsp)
    movw    $13105, 4(%rsp)         # imm = 0x3331
    leaq    4(%rsp), %rdi
    callq   blah
    movsbl  5(%rsp), %esi
    movl    $.L.str, %edi
    xorl    %eax, %eax
    callq   printf
    xorl    %eax, %eax
    popq    %rcx
    retq

现在,它从 tests 中获取值。

关于c++ - 编译器是否优化对常量变量的引用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41224516/

相关文章:

c++ - 保持 GUI 独立

android - 在推送上运行一次性 GCM 网络管理器任务

python - 优雅与性能 : When to use redundant lists for queries?

c++ - 在 map 上调用保护区时出现访问冲突

c++ - union 成员的析构函数似乎被自动调用

c++ - 尝试发送包含字符数组的数据包时出现段错误(核心已转储)

c - 如何在 Ubuntu 的默认文件夹之外编译 ffmpeg 示例?

c - Argc/Argv C 问题

C - 按计数然后按字母顺序 Qsort

javascript/canvas : draw polylines in real-time, 什么是最优数据结构?