在渲染代码中,我将字符串文字作为参数传递给渲染块,以便可以在调试转储和性能分析中识别它们。它看起来类似于:

// rendering client
draw.begin("east abbey foyer");
    // rendering code
draw.end();

void Draw::begin(const char * debugName){
    #ifdef DEBUG
        // code that uses debugName
    #endif
    // the rest of the code doesn't use debugName at all
}

在最终程序中,我不希望这些字符串出现。但我也想避免在渲染客户端代码中使用宏来执行此操作;实际上,我希望渲染客户端代码保留字符串(在代码本身中),但实际上不将其编译到最终程序中。

因此,我想知道的是,如果我将draw.begin(const char*)的代码更改为根本不使用它的参数,我的编译器是否会优化该参数及其相关的开销(甚至可能甚至将其从字符串表中排除)?

最佳答案

实际上,这取决于编译器是否可以访问Draw::begin()实现的源代码

这是一个例子:

#include <iostream>

void do_nothing(const char* txt)
{

}

int main()
{
    using namespace std;
    do_nothing("hello");
    return 0;
}

用-O3编译:

产量:
_main:                                  ## @main
    .cfi_startproc
## BB#0:
    pushq   %rbp
Ltmp3:
    .cfi_def_cfa_offset 16
Ltmp4:
    .cfi_offset %rbp, -16
    movq    %rsp, %rbp
Ltmp5:
    .cfi_def_cfa_register %rbp
    xorl    %eax, %eax
    popq    %rbp
    retq
    .cfi_endproc

即字符串和对do_nothing的调用已完全优化

但是,在另一个模块中定义do_nothing,我们得到:
_main:                                  ## @main
    .cfi_startproc
## BB#0:
    pushq   %rbp
Ltmp0:
    .cfi_def_cfa_offset 16
Ltmp1:
    .cfi_offset %rbp, -16
    movq    %rsp, %rbp
Ltmp2:
    .cfi_def_cfa_register %rbp
    leaq    L_.str(%rip), %rdi
    callq   __Z10do_nothingPKc
    xorl    %eax, %eax
    popq    %rbp
    retq
    .cfi_endproc

    .section    __TEXT,__cstring,cstring_literals
L_.str:                                 ## @.str
    .asciz  "hello"

即多余的负载,调用和字符串的地址被传递。

因此,如果您想优化调试信息,则需要内联实现Draw::begin()(与STL相同)。

07-24 09:51
查看更多