gst
gst

Reputation: 1285

Loss of volatile qualification

I have a code running through in some safety critical automotive module. The following is a rough estimation of the code :

The below code is a part of a module - "Main Module" , that owns the volatile variable/array "x_ast"

Main Module.c

//The structure x contains the major data that needs to be stored in case of a crash event. i.e. a real car crash
// x contains data such a vehicle speed, environment data, sensor data, CAN related data,etc. Basically x itself has lot of structures inside it.


typedef struct x x_tst;
volatile x_tst x_ast[5];
//x_ast is being used in realtime and background functions, considering proper interrupt disabling and enabling.

The below code is a part of a module - "DependentModule" that enables sharing of buffer "x_ast".

DependentModule.c

extern volatile x_tst x_ast[5];


//x_ast is owned by a separate module
//Now I need to share this buffer "x_ast" to a different module that will inturn fill data in it for some conditions. Say for a particular condition that is activated, the buffer "x_ast" will be shared across to a module "Conditional Data Record". 
//The base address of first indexed buffer "x_ast[1]" is provided to "Conditional Data Record" for access. 
//The main module will not access the buffer that is shared, once the "Conditional Data Record" is activated/requested. 

// Below is a mechanism to share the buffer "x_ast" to module "Conditional Data Record".

// This API will be called by module - "Conditional Data Record" once it is activated. It is ensured that this takes place only during intialization of whole system, and no other time.

boolean GetConditionalBuffer(uint8 **PtrToBuffer)
{
  boolean BufferShared = FALSE;
  void* Temp_ptr;
  *PtrToBuffer = NULL;

// if module  "Conditional Data Record" is activated? then share the buffer "x_ast", else do not share the buffer.

if(Conditional Data Record == activated) {
   Temp_ptr = (x_tst*)&x_ast[1];
   *PtrToBuffer = Temp_ptr;
   BufferShared = TRUE;
}

return BufferShared;

}



Referring to the line of code:
Temp_ptr = (x_tst*)&x_ast[1];

The above line of code (Tempptr = (x_tst*)&x_ast[1];) throws a warning "Msg(7:0312) Dangerous pointer cast results in loss of volatile qualification." The above warning is a mandatory warning and hence it becomes necessary to resolve it.

I do understand that I am assigning an address of volatile variable to a void pointer that results in loss of volatile qualification. I have tried different ways trying to resolve the warning, but could not get a conclusive way.

Is there any way, I could modify the code and remove this warning, or may be bypass this warning.

Upvotes: 0

Views: 221

Answers (1)

gnasher729
gnasher729

Reputation: 52602

If you assign a value to a volatile object or read the value of a volatile object without using a volatile-qualified pointer, you get undefined behaviour.

The compiler has to treat volatile objects in a stricter way than non-volatile objects (that means treating a non-volatile object as if it was volatile is fine, treating a volatile object as if it was non-volatile can have bad consequences).

Casting the address of a volatile object to a non-volatile pointer is putting you at severe risk. DON'T DO IT. Whoever uses that void* pointer is in big risk of invoking undefined behaviour. For example, just using memcpy to copy that volatile array is undefined behaviour. Anything, and usually bad things, could happen.

Declare that function as

boolean GetConditionalBuffer(volatile x_tst **PtrToBuffer)

because volatile x_tst* is what it stores into PtrToBuffer. Why would you throw away type information? I'd actually change it to

volatile x_tst* GetConditionalBuffer (void);

which makes it easier on the poor developer's brain, and makes the function easier to use.

Upvotes: 1

Related Questions