Jump to content
  • 0

I used to use @ to locate variables but since XC8 2.0 this is no longer working?



  • Member

I have a bunch of old projects using the @ method to hard locate variables at a specific location in data memory, but since I upgraded to XC8 2.0 none of these are working any more!

How do I do this with the latest compiler? I am using XC8 v2.xx.

I also saw this error at my interrupt service routine and I suspect that this is the same problem.

My interrupt code looks like this 

void interrupt my_isr(void) {
   ... my code here  

error: variable has incomplete type 'void'

Link to comment
Share on other sites

2 answers to this question

Recommended Posts

  • Member

I came across this and thought I would post it here in case others hit the same snag.

In the past it was possible to hard locate a variable using XC8 like this :

 volatile unsigned char   TMR0    @ 0x01;

Although this was convenient it was also not strictly acceptable C syntax, so if you were using a linter on your code to check if you have anything untoward in there it could flag this as being incorrect C syntax.

In XC8 v2.0 the syntax was switched to what Microchip calls the CCI (Common Compiler Interface) syntax, which uses the following syntax to hard locate a variable.

volatile unsigned char TMR0 __at(0x01);

Since this has a double underscore and the brackets it is more compliant to the C standards.

With XC8 2.0 it is possible to compile your old code using the @ syntax if you set the compiler settings to use "C90" format. The setting looks like this, it is under "XC8 Global Options" and is called "C standard".



If you want to use something which does not use a compiler specific extension such as @ or __at() you can always do it like this:

// This defines the TMR0 register - volatile is important to tell the compiler that this is a volatile register, 
// read more about volatile in the XC8 Users Guide
#define TMR0 (*(volatile uint8_t*)0x0001u)  
// You can now access it like normal, something like this.
TMR0 = 0x12;

Hope that helps 🙂

There are a couple of other CCI keywords which are described in the compiler user's guide such as __interrupt which you can also get to work by switching back to the pre 2.0 syntax by choosing "C90" as shown above.

I also posted about this on the Microchip forum on this thread. Below is a copy of that post.


Hi Guys here is the full story:

With XC8 2.0 we are very excited that we get an improved compiler front-end, which brings things like C99features to us which we are very happy to have.
Unfortunately pre-XC8 2.0 we had some keywords in the compiler which were not strictly conforming to the C standard. 
Keywords like these:

  1. Using "bit" as a variable type
  2. Using "interrupt" to mark interrupt functions
  3. Using "int i @0x88" to hard locate a variable at a ram location
  4. Using "#asm" to create inline assembly.

Together with the wonders we get with the new front-end we have also lost support for the "old" way of doing these things which was not strictly standards compliant. XC8 has for a while allowed the corrected syntax but with 2.0, due to the improved front-end implementation, these non-standard keywords are no longer available.
Unfortunately MCC has been using too many of this pre-XC8 2.0 syntax and this can now cause some compatibility issues.
To minimize problems the IDE will default any "old project" you open (and change the compiler to XC8 2.0) to pass in "C Standard = C90" which can be set under "XC8 Global Options". This will tell the compiler to use the pre-XC8v2.0  front-end to compile your code which should give you the same behavior you got before with XC8v1.45 and earlier. If you use MCC with this project you should experience no problems.
When you make a new project it will default to "=C99" which means the deprecated syntax will cause compilation errors where the above syntax was used. You can get these projects to work easily by either fixing the code to use the standards-compliant CCI syntax - or changing the define to C90 and leave the code unchanged (leaving the problem for later so to speak)
The correct syntax is (the underscores are all double-underscores btw.):

  1. "__bit" for the "bit" type
  2. "__interrupt()" instead of just "interrupt" - yes the brackets are required.
  3. To hard locate a variable use e.g. "int i __at(0x88)"
  4. For inline asm use "asm()"

There are also a couple of small issues which should be resolved in the next compiler release. These are:

  1. The int24_t type define in stdint.h is not present for C99 mode, it will be there soon.
  2. There is a change in the Vectored Interrupt vector names which we are still looking into, contact me if you run into this one and I can help.

We have released a new version of the MCC 8-bit libraries which will addresses these issues by converting the code to CCI compatible syntax which will make it work on all modes and versions of the XC8 compiler. This can be downloaded from microchip.com/mcc. 

The first version of the libraries with the update is v1.75 


Link to comment
Share on other sites

  • Member

There is actually a lot of information on this in the Release Notes for the compiler and also in the XC8 Compiler Users's Guide.


This has also been a very interesting resource on how the compiler can be used more effectively on embedded projects.



Link to comment
Share on other sites


This topic is now archived and is closed to further replies.


  • Create New...