In my C code I have an external symbol, some_symbol
. I need to get the address of the memory position just preceding that symbol (&some_symbol-1
). This used to work fine in older versions of gcc, but on gcc 12.2.0 with -O2 enabled I get an array-bounds warning:
#include <stdio.h>
extern void *some_symbol;
int main (void) {
printf ("%p\n",&some_symbol-1);
return 0;
}
$ cc -Wall -O2 -c x.c -o x.o
x.c: In function ‘main’:
x.c:6:9: warning: array subscript -1 is outside array bounds of ‘void[8]’ [-Warray-bounds]
6 | printf ("%p\n",&some_symbol-1);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
x.c:3:14: note: at offset -8 into object ‘some_symbol’ of size 8
3 | extern void *some_symbol;
| ^~~~~~~~~~~
I understand why this is dangerous. But in this case, I'm referring to a symbol from the run time system of another language, and the RTS documents that there is space above this symbol, which in some cases needs to be referenced. Here is an example of what the RTS does:
.data
some_symbol_name:
.string "some_symbol\0"
.text
.quad some_symbol_name
.globl some_symbol
some_symbol:
# ...
I can circumvent the problem using uintptr_t
:
printf ("%s\n",*(char**)(&some_symbol-1));
printf ("%s\n",*(char**)((intptr_t)&some_symbol-sizeof(void*)));
Both of these correctly print some_symbol
, but the first gives a compilation warning similar to the one above.
The API of the external system guarantees that there is readable data above some_symbol
, but how do I tell this to gcc? Using uintptr_t
everywhere is unwieldy.
I know that I can disable the warning (locally), but would prefer not to.
Is there a way to specify in the extern
declaration of the symbol that there is space before the symbol that can be referenced?