Electronic – get a compiler warning with “int __attribute__((address(0x3000))) x;”

microchippicvariable

I am trying to understand why I get the following warning

#include <xc.h>

int main (void)
{
     int __attribute__((address(0x3000))) x;


     while(1);

     return 0;
 }

PIC24_Attributes.c:13:5: warning: ignoring address attribute applied to automatic x

I know __attribute__address((address(0x3000))) x means store the variable of type int x in DATA SPACE address 0x3000

When I download the program, and debug it, I see that the address of x is 0x856

but when I put it globally the warning disappears, and when I debug, the address of x is 0x3000.

I googled the warning I got, and I found someone with the same warning as me, but with the space attribute instead (http://www.microchip.com/forums/m351172.aspx)

From what I understood was __attribute__ only works for static variables, and automatic variables (don't know why it is automatic, it is an int) are allocated dynamically.

Can someone explain this please, as I understand that `attribute((address(…)))' means store the following variable at a certain address.

  • Microncotroller: PIC24FJ1024GB610 (Microchip)
  • Debugger: PKOB (Explorer 16/32 Development Board)

Best Answer

Automatic refers to the C concept of automatic storage duration. In C, there are chiefly 2 different storage durations for objects: static (not to be confused with the static keyword, which is a storage-class specifier) and automatic. An object shall retain its last stored value and will be stored at a constant address for the entire duration of its lifetime.

Static storage duration means "the duration of the entire program" - that is, from before entering the main the first time up to after exiting it.

Automatic storage duration is for objects "declared with no linkage and without the storage-class specifier static" - the no linkage means that they're not declared globally - they're declared/defined within a block, and not declared with storage-class specifier extern. Their lifetime is chiefly to the end of the block.

Now in your program,

#include <xc.h>
int main (void)
{
     int __attribute__((address(0x3000))) x;
     while(1);
     return 0;
}

Since the declaration-definition int x; it has neither the extern nor static storage-class specifier, it defines an int object of automatic storage duration within the main function. Each time the main function is entered, a new distinct object must be allocated. C allows the main function to call itself recursively too, so clearly x simply cannot be at a fixed address here. In fact, on many computer architectures x might not even reside in memory at all - it might be in a register, or optimized out completely.


It makes sense only to have an object that has static storage duration, as opposed to automatic storage duration, to be located at a fixed address. In addition to declaring this at the file scope:

int __attribute__((address(0x3000))) x;
int main(void) { ... }

which would make x accessible everywhere within the file, you can also make the identifier private to the main function, but still retain the static storage duration, by using the static storage-class specifier:

int main(void) { 
    static int __attribute__((address(0x3000))) x;
    ... 
}

Now, the identifier x is not visible outside the main function; and exactly only one x is defined, and its storage duration is static, which means that it is for the entire duration of the program - as its storage duration is not automatic, but it will have a fixed address for the entire runtime of the program, the compiler can be asked to locate it at an alternate address.