analyzing some code:
static volatile UCHAR *pucSndBufferCur;
eMBErrorCode eMBRTUSend( UCHAR ucSlaveAddress, const UCHAR * pucFrame, USHORT usLength )
{
if( eRcvState == STATE_RX_IDLE )
{
/* First byte before the Modbus-PDU is the slave address. */
pucSndBufferCur = ( UCHAR * ) pucFrame - 1;
/* Now copy the Modbus-PDU into the Modbus-Serial-Line-PDU. */
pucSndBufferCur[0] = ucSlaveAddress;
It looks like unsafe, what if memory in address (pucFrame - 1 ) is already used for other variable and overwriting it could cause malfunctions.
What do you think, is code like this can be used or its wrong way and never should be used ?
From this comment
/* First byte before the Modbus-PDU is the slave address. */
pucSndBufferCur = ( UCHAR * ) pucFrame - 1;
we might infer that the function expects the caller to guarantee this. In that case, if the caller fulfils the requirement, then the code is safe.
If the caller doesn't guarantee this, the function is not safe. This is just like any other pre-requisite you can't usefully check: they have UB if the requirement is violated and this is the caller's fault.
For comparison, free()
will likely have similar behaviour (and probably worse side-effects) if you violate the pre-requisite that its pointer argument was returned from malloc()/realloc()
.
It looks like unsafe, what if memory in address (pucFrame - 1 ) is already used for other variable and overwriting it could cause malfunctions
It is unsafe - it's C. The responsibility for using it correctly is yours. If you use it wrongly (passing a pointer that does not meet the stated requirement), there will be malfunctions and they will be your fault.
What do you think, is code like this can be used or its wrong way and never should be used ?
It can be used safely, just as free()
can be used safely. It can be used the wrong way just as free()
can be misused. The only reason to never use code like this is that you don't trust yourself to use it correctly.
The practical advice is to look at where this pucFrame
pointer comes from, verify that it is always guaranteed to meet the requirement, and then make sure you don't break anything in the pointer's journey through your code.