8.4.2. Bit manipulation operations

Take care to ensure that bitmasks are of the correct width. There is the possibility that implicit type conversions in C expressions can have some unexpected effects. Consider the following function for setting a specified bit in a 64-bit variable:

  long SetBitN(long value, unsigned bitNum)
  {
     long mask; 
     mask = 1 << bitNum;
     return value | mask;
  }

This function works fine in a 32-bit environment and allows bits [31:0] to be set. To port it to a 64-bit system, you might think it sufficient to change the type of mask to allow bits [63:0] to be set, as follows:

  long long SetBitN(long long value, unsigned bitNum)
  {
     long long mask; 
     mask = 1 << bitNum;
     return value | mask;
  }

Again, this does not work correctly as the numeric literal 1 has int type. The exact behavior depends on the configuration and assumptions of the individual compiler.

To make the code function correctly, you need to give the constant the same type as the mask:

  long long SetBitN(long long value, unsigned bitNum)
  {
     long long mask; 
     mask = 1LL << bitNum;
     return value | mask;
  }

If you need an integer that is a particular size, use types such as uint32_t and the UINT32_C family of macros, which are defined in stdint.h.

Copyright © 2015 ARM. All rights reserved.ARM DEN0024A
Non-ConfidentialID050815