如何告诉 gcc 保留我未使用的标签?

onl*_*rra 12 c assembly gcc compiler-flags

编辑:感谢@NateEldredge,我在如何在 C 源文件中“标记”位置以供以后断点定义中更好地定义了我的问题?


我使用这些标签在 gdb 中设置断点。因此,无论我在标签之后/之前添加/删除代码行,断点仍然是正确的。

如果我添加-Wno-error=unused-label到编译选项,编译器不会对我大喊大叫,但标签会从程序集中消失。

相反,如果我__attribute__((unused))在代码中使用,结果是相同的:没有抱怨,但标签消失了。

有没有正确的方法来完成这个任务(而不仅仅是黑客)?

这是我的玩具示例:

int main(void){
    int a = 15;
 label: __attribute__((unused))
    a = a + 23;
    return a;
}
Run Code Online (Sandbox Code Playgroud)

编译后结果为:

main:
        push    ebp
        mov     ebp, esp
        sub     esp, 16
        mov     DWORD PTR [ebp-4], 15
        add     DWORD PTR [ebp-4], 23
        mov     eax, DWORD PTR [ebp-4]
        leave
        ret
Run Code Online (Sandbox Code Playgroud)

这是同一示例的交互式版本: https: //godbolt.org/z/zTqd9bM6q


int main(void){
    int a = 15;
 label: __attribute__((unused))
    a = a + 23;
    return a;
}
Run Code Online (Sandbox Code Playgroud)

Dav*_*son 7

如果您希望标签不被删除或重命名,请尝试以下操作:

    asm volatile("mylabel:");
Run Code Online (Sandbox Code Playgroud)

请注意,拥有此标签可能会影响 GCC 优化函数的方式。但是,该volatile关键字可能有助于防止它执行任何可能导致问题的操作。

另请注意,您可以使用__asm__代替asm. 两者似乎都在 GCC 中工作。

  • 正如问题下的评论中所讨论的,在内联或循环展开时这会出现问题,因为标签将位于一个“.s”文件中的多个位置(这是一个错误)。另外,不要使用 GNU C Basic Asm;最近的 GCC 版本将非空 Basic asm 模板字符串视为具有“内存”破坏者,因此会不必要地损害优化。如果您想强制编译器使内存(非转义局部变量除外)与 C 抽象机同步,请显式使用 `asm("mylabel:" ::: "memory");`,或者 `asm(" mylabel:" :::);` 如果没有。 (2认同)

orl*_*rlp 4

您可以使用以下命令使未使用的标签警告静音:

int main(int argc, char** argv) {
    int a = 15;
    goto label; label:
    a = a + 23;
    return a;
}
Run Code Online (Sandbox Code Playgroud)

这会将标签保留在程序集中(尽管使用内部名称):

main:
.LFB0:
        push    ebp
        mov     ebp, esp
        sub     esp, 16
        mov     DWORD PTR [ebp-4], 15
        nop
.L2:
        add     DWORD PTR [ebp-4], 23
        mov     eax, DWORD PTR [ebp-4]
        leave
        ret
Run Code Online (Sandbox Code Playgroud)

我建议使用宏来减少工作量并更好地表达意图:

main:
.LFB0:
        push    ebp
        mov     ebp, esp
        sub     esp, 16
        mov     DWORD PTR [ebp-4], 15
        nop
.L2:
        add     DWORD PTR [ebp-4], 23
        mov     eax, DWORD PTR [ebp-4]
        leave
        ret
Run Code Online (Sandbox Code Playgroud)

  • @onlycparra:那么 C 标签对于您的用例来说一直是无用的,因为它们不会转换为汇编中具有相同名称的标签。(如果您考虑一下,这是行不通的:不同的函数可以包含具有相同名称的标签,更不用说内联了。) (2认同)
  • @onlycparra:此时我可能会将其作为一个全新的问题发布,也许带有指向此问题的链接。 (2认同)