CF should use unions to simplify code and avoid improper casting
This issue was imported from the GSFC issue tracking system
Imported from: [GSFCCFS-1796] CF should use unions to simplify code and avoid improper casting Originally submitted by: Hickey, Joseph P. (GSFC-582.0)[VANTAGE SYSTEMS INC] on Wed Nov 17 09:29:11 2021
Original Description: In particular this applies to the "msg" member of the global, in the following structs:
CF_AppData.engine.out.msg
CF_AppData.engine.in.msg
They are currently defined as a "CFE_SB_Buffer_t*" type, which is what comes to/from SB calls. However, locally it is either a "pdu_s_msg_t" or "pdu_r_msg_t" (an extension) depending on direction. This is then cast inline at the point of use whenever the local type is required, e.g.
ret = &((pdu_s_msg_t *)CF_AppData.engine.out.msg)->ph;
This is not only inelegant, but casting permits almost any type conversion, and offers no protection against a programmer mistake, such as if it was cast to a "pdu_r_msg_t*" instead of "pdu_s_msg_t*" .. that would compile just fine but cause odd memory corruption at runtime.
Recommend to use a union for the "msg" member data type, i.e.
union
{
CFE_SB_Buffer_t sb_buf;
pdu_r_msg_t pdu_r_msg;
};
Then by taking the address of either the "sb_buf" or "msg" union member depending on what is being called and what it requires.
In addition to being easier to read, this offers a layer of protection in that the data can only be converted into a limited set of types (union members).