Consider the simple program:
#define kHiddenNumber 1234567
int main(void)
{
int i = kHiddenNumber;
return(i & 0xFF);
}
Compile it:
gcc -o xx xx.c
Note that 123456710 = 0x12D687
Now print the program in hex and search for D6:
$ od -x xx | grep d6
0002700 6d65 422e 642e 6c79 6269 0000 0000 0000
0007460 45c7 87fc 12d6 0f00 45b6 c9fc 00c3 25ff
0020140 7265 4700 705f 6f72 6e67 6d61 0065 026c
$
You can see the 0x12D687 in there, in the middle line of output. It's in a funny format, but nonetheless present in the code. Note that the compilation was not optimized. When the program is optimized, the evidence is lost - probably because the constant is used in such a simple context that 'i' can be optimized out and the return expression reduced to the value 0x87. The byte 0x87 does appear in the optimized code at about the same place in the optimized version - you'd need to do a proper disassembly job to prove that was definitively the last byte of the value, though I regard it as likely.
$ od -x xx | grep -i d6
0002320 e500 60d6 fdf5 ee77 10b8 e3d5 5834 7377
0002700 6d65 422e 642e 6c79 6269 0000 0000 0000
0020140 7265 4700 705f 6f72 6e67 6d61 0065 026c
$ od -x xx | grep -i 87
0007460 0000 f400 4855 e589 87b8 0000 c900 00c3
$
In more complex programs - where 'i' was passed to a function (perhaps 'printf()'), the optimization could not be done.
Consequently, you cannot rely on the compiler to hide the value. The name for the value will be absent, most likely. But the value may well be present in the program to be found.
Incidentally, you can sometimes find encryption keys in a similar - though more complex way. The data is too random to be natural - so it stands out like a sore thumb in the program.