Edit: Thanks to @NateEldredge, I better defined my question in How to 'tag' a location in a C source file for a later breakpoint definition?
I use those labels to setup breakpoints in gdb. So no matter if I add/remove lines of code after/before the label, the breakpoint is still correct.
If I add -Wno-error=unused-label
to the compilation options, the compiler does not yell at me, but the label disappears from the assembly.
If instead, I use __attribute__((unused))
in the code, the result is the same: no complain, but the label is gone.
Is there a correct way of getting this done (instead of just a hack)?
Here is my toy example:
int main(void){
int a = 15;
label: __attribute__((unused))
a = a + 23;
return a;
}
After compilation, it results in:
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
Here an interactive version of the same example: https://godbolt.org/z/zTqd9bM6q
$ gcc --version
gcc (GCC) 10.3.1 20210422 (Red Hat 10.3.1-1)
Copyright (C) 2020 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
goto
right before the label. – Standpipe__asm__("label:");
– Elfriedeelfstan__attribute__((unused))
is unrelated to what you are trying to do. It is merely suppressing the "unused" warning. – Fucoid#if DEBUG … #endif
), such asvolatile int x; switch(x) { case 0: goto foo; case 1: goto bar; … }
. – Parnell__asm__("label:");
works as expected. Beautiful. Thanks. @Jester, If you could please post an answer based on your comment, I would gladly mark it as a correct answer. | Edit: It seems that there are some issues with this approach, as @EricPostpischil mentions – Resigned__asm__("label:")
can fail. During optimization, the compiler might decide to duplicate code, resulting in the label appear twice in assembly code, which will usually cause compilation to fail. Or it might be removed when the compiler determines execution can never pass through it (although then putting a breakpoint there would be useless anyway, as it would never be hit). – Parnell#ifdef DEBUG ... #endif
approach. I cannot achieve the desired output godbolt.org. Also, should I define/undefineDEBUG
from the C file, or that can be done in the Makefile? – Resigned__asm__("label:")
approach; I am compiling with-O0
or-Og
. Do you know if the compiler would perform those pernicious optimizations if I am asking to gcc not to touch my code too much? – Resignedasm
statement breaks in interesting ways when the function is inlined. – Innerror: 'used' attribute ignored
. I don't know if that implies that in generalunused
does not apply to labels. But it doesn't work here. – Resigned"memory"
clobber, so doing that would affect the optimizer. (Possibly moreso than getting the compiler to emit an asm label). This is undocumented and thus not recommended to rely on; it's a sop to bad code that should be using Extended asm for a"memory"
clobber to control ordering for stuff likeasm("mfence")
or enable/disable of interrupts. – Alecaleciasource.c:line
works, but if I add one line on the top of the file, everything gets shifted. – Resigned