I'm programming C on an embedded system. The processor architecture is 32 bits (sizeof(int)
is 32 bits, sizeof(short)
is 16 bits). There is a 32-bit variable that is a memory-mapped control register (CTRL_REG
) that is specified as only the bottom 16 bits being used, and they contain a signed 16 bit integer value (writing to the higher bits has no effect). Memory accesses must be 32-bit aligned, so I can't just bump the pointer over a couple bytes, and also I cannot assume an endianness. I'm concerned that automatic type promotion is going to mess with whatever I'm storing by extending the sign bit out to bit 31 instead of leaving it at bit 15 where I want it. What is the best way to store something in this location?
Here was my original code, which I am nearly certain is wrong:
#define CTRL_REG *((volatile unsigned int *)0x4000D008u)
short calibrationValue;
CTRL_REG = -2 * calibrationValue;
Then I tried this, but I think it still might be subject to integer promotion at the point of the assignment:
CTRL_REG = (short)(-2 * calibrationValue);
Then finally I thought of this:
CTRL_REG = (unsigned short)(short)(-2 * calibrationValue);
I can't evaluate these options very well because they all work in my tests because calibrationValue
happens to be negative (it's a calibration parameter specific to each device, and so could be positive on some devices), so after multiplying by -2, I end up storing a positive value and thus I don't actually run into the problem I'm expecting in my tests.
Your help is greatly appreciated, even if it's just to say "you're thinking too much".