Why do I get a compiler warning with "int __attribute__((address(0x3000))) x;"
x is a local variable. It doesn't necessarily even get a storage address. So, you can't necessarily assign an address to it.

Make x global. 

"automatic" is the storage type of a variable, not the data type, so it being int is orthogonal to it being static or automatic.

It's a bit surprising your debugger sees an address for the main-local x at all – it'd be totally appropriate of the compiler to see that x, analyze where it's used, see it's used nowhere, and simply don't assign any location at all.

For example:

test_temp_storage.c

/* test_temp_storage.c */
int main()
{
  int x;
  while(1);
  return 0;
}


building, with -Os, something that every sensible human would do to a microcontroller-targetting compiler (optimizing for code size):

$&gt; clang -g -Os -o test test_temp_storage.c


debugging, break before entering while loop:

$&gt; gdb test
(gdb) break test_temp_storage.c 
Breakpoint 1 at 0x400490: file test_temp_storage.c, line 5.
(gdb) run
Starting program: /home/marcus/src/scratch/test 

Breakpoint 1, main () at test_temp_storage.c:5
5     while(1);
(gdb) print x
$1 = &lt;optimized out&gt;
(gdb) print &amp;x
Can't take address of "x" which isn't an lvalue.


As you can see, there's no x here in existence.