# XC8, error, expression may have no targets

#### bug13

Joined Feb 13, 2012
1,846
Hi team

How do I get rid of this error:
cbuff.c:111:: warning: (1498) pointer (CBUFF_OBJ_construct@cbuff) in expression may have no targets
Here is my code, as you can see, all pointers are already checked.
C:
CBUFF_OBJ_Handle CBUFF_OBJ_construct(volatile CBUFF_OBJ_Struct *cbuff, volatile uint8_t *data, uint16_t obj_size, uint16_t capacity){

/* make sure pointers are valid */
if (cbuff == 0) return 0;
if (data == 0) return 0;

/* all pointers below have this warning */
cbuff->capacity = capacity;
cbuff->count = 0;
cbuff->tail = 0;
cbuff->data = data;
cbuff->obj_size = obj_size;

return (CBUFF_OBJ_Handle)cbuff;
}

#### bug13

Joined Feb 13, 2012
1,846
PS:
XC8 compiler, free mode, v2.2

#### WBahn

Joined Mar 31, 2012
25,760
My guess is that the problem is that you have declared cbuff as volatile, and so it may have changed since it was checked. I have very little experience working with volatile data types, so I could be way off base.

#### bug13

Joined Feb 13, 2012
1,846
My guess is that the problem is that you have declared cbuff as volatile, and so it may have changed since it was checked. I have very little experience working with volatile data types, so I could be way off base.
Very good observation about volatile, I thought that was the reason until I tested out. Same error again after the volatile key word is removed.

C:
CBUFF_OBJ_Handle CBUFF_OBJ_construct(CBUFF_OBJ_Struct *cbuff, uint8_t *data, uint16_t obj_size, uint16_t capacity){

/* make sure pointers are valid */
if (cbuff == 0) return 0;
if (data == 0) return 0;

/* same error after removing volatile keyword */
cbuff->capacity = capacity;
cbuff->count = 0;
cbuff->tail = 0;
cbuff->data = data;
cbuff->obj_size = obj_size;

return (CBUFF_OBJ_Handle)cbuff;
}

#### WBahn

Joined Mar 31, 2012
25,760
Are you sure that your declaration of the structure and its members is visible in this file? I would expect other issues would pop up if it wasn't, but embedded system compilers can be a strange critter.

Try putting the structure declaration in this file and see if that changes anything. If that doesn't help, start off with a new structure declaration (use the same name but append a digit or underscore or something to make it different) that is simple and all in this file. If that works, then incrementally modify that declaration and the code that uses it until you have something that is identical to the problematic one. At some point things should go off the rails and that is where the issue is (or at least where it leaves fingerprints), so make your changes very small as you go.

#### bug13

Joined Feb 13, 2012
1,846
Are you sure that your declaration of the structure and its members is visible in this file? I would expect other issues would pop up if it wasn't, but embedded system compilers can be a strange critter.

Try putting the structure declaration in this file and see if that changes anything. If that doesn't help, start off with a new structure declaration (use the same name but append a digit or underscore or something to make it different) that is simple and all in this file. If that works, then incrementally modify that declaration and the code that uses it until you have something that is identical to the problematic one. At some point things should go off the rails and that is where the issue is (or at least where it leaves fingerprints), so make your changes very small as you go.
Yes the declaration of the structure and its members is visible in this file. As I can use this function as expected no problem.

I got a feeling that this has something to do with the strange behavior the the XC8 compiler, there are a few post about this on Microchip forum.

#### 402DF855

Joined Feb 9, 2013
202
Which line is 111, the one flagged with the warning? One thing, it is highly unusual IME to declare the argument of a function as volatile. Don't think I've ever seen that before. Not to say it's wrong, this might be a chance to learn something new for me, will look into it.

This might be pertinent, mentions the free compiler and optimization.

https://www.microchip.com/forums/m1058757.aspx

#### bug13

Joined Feb 13, 2012
1,846
Which line is 111, the one flagged with the warning? One thing, it is highly unusual IME to declare the argument of a function as volatile. Don't think I've ever seen that before. Not to say it's wrong, this might be a chance to learn something new for me, will look into it.

This might be pertinent, mentions the free compiler and optimization.

https://www.microchip.com/forums/m1058757.aspx
Here are my code, starting from line 111 to line 116, all have the same error:
C:
    cbuff->capacity = capacity;    // line 111
cbuff->count = 0;            // line 112
cbuff->tail = 0;            // ...
cbuff->data = data;            // ...
cbuff->obj_size = obj_size;    // line 116
Here is the explanation of the function, the reason I use volatile is they will be modified inside and outside an interrupt. My understanding is all variable use inside and outside interrupt need to be volatile? As the compiler can't tell when the values will be updated?

C:
/*! \brief Construct the initialize the ring buffer
*! \param volatile CBUFF_OBJ_Struct *cbuff      - pointer to the object ring buffer structure
*! \param volatile uint8_t *data                - pointer to the ring buffer memory location
*! \param uint16_t obj_size                     - size in byte of the object
*! \param uint16_t capacity                     - Maximum number of object that can be stored in the buffer
*! \return CBUFF_OBJ_Handle                     - handle to object ring buffer
*/
CBUFF_OBJ_Handle CBUFF_OBJ_construct(volatile CBUFF_OBJ_Struct *cbuff, volatile uint8_t *data, uint16_t obj_size, uint16_t capacity);

#### 402DF855

Joined Feb 9, 2013
202
volatile CBUFF_OBJ_Struct *cbuff
You are telling the compiler that the pointers to the buffers are volatile, I mean the actual addresses, not the contents of the buffers. That's hard to wrap my mind around. Arguments to a function are ordinarily stored in registers, and if needed, on the stack, sometimes one then the other, as needed. This of course depends on the part and compiler. My swag is the optimization limited version of the compiler isn't well adapted to the declarations you've provided. Ultimately does the code work? If the paid version of the toolset doesn't complain then it's probably a non-issue.

#### bug13

Joined Feb 13, 2012
1,846
You are telling the compiler that the pointers to the buffers are volatile, I mean the actual addresses, not the contents of the buffers. That's hard to wrap my mind around. Arguments to a function are ordinarily stored in registers, and if needed, on the stack, sometimes one then the other, as needed. This of course depends on the part and compiler. My swag is the optimization limited version of the compiler isn't well adapted to the declarations you've provided. Ultimately does the code work? If the paid version of the toolset doesn't complain then it's probably a non-issue.
I don't have a paid version either, been using the free version all the time.

I think this is what you mean, the pointer is volatile:
C:
/* pointer is volatile, but the content pointing to is not volatile */
CBUFF_OBJ_Struct * volatile cbuff;
But, this mean the content pointing to is volatile:
C:
/* the content pointing to is volatile, the pointer is not volatile */
volatile CBUFF_OBJ_Struct *cbuff;

#### 402DF855

Joined Feb 9, 2013
202
I think this is what you mean, the pointer is volatile:
Now that my beer fog has mostly lifted I see you are right, my observation was mistaken. But keep in mind that how the compiler applies volatile declarations is implementation dependent. And volatile is generally used to instruct the compiler to eliminate optimizations. I suspect the warning is related to how the function is being called (or not called?). For example:

C:
CBUFF_OBJ_construct( (volatile CBUFF_OBJ_Struct *) 0, (volatile uint8_t *) 0, 0, 0);
If you are unable to eliminate the warning and it still bothers you, it would make sense to go over the emitted assembly language and ensure that it is right. The function is very simple so this should not take much effort.

CBUFF_OBJ_construct( (volatile CBUFF_OBJ_Struct *) 0, (volatile uint8_t *) 0, 0, 0);