Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Oppiskele Safe Shifting Rules | Bitwise Operators and Shifts
C Bitwise Operations and Binary Logic

bookSafe Shifting Rules

Bit shifting in C can cause undefined behavior if used incorrectly, leading to crashes or inconsistent results across compilers. Avoid shifting by negative values, shifting by an amount greater than or equal to the bit width, and shifting negative numbers, especially with right shifts. These mistakes break portability and program safety.

safe_unsafe_shifts.c

safe_unsafe_shifts.c

copy
123456789101112131415161718192021222324252627282930
#include <stdio.h> #include <limits.h> int main() { unsigned int a = 1; int b = -8; int shift_amount = 32; // Safe left shift: within type width, unsigned type unsigned int safe_left = a << 3; // 1 shifted left by 3 is 8 // Safe right shift: unsigned type, within range unsigned int safe_right = a >> 1; // 1 shifted right by 1 is 0 // Unsafe left shift: shift amount >= type width (undefined behavior) unsigned int unsafe_left = a << shift_amount; // undefined if shift_amount >= 32 // Unsafe right shift: negative shift amount (undefined behavior) // unsigned int unsafe_right = a >> -1; // Uncommenting this is always undefined // Unsafe right shift: signed negative value (implementation-defined or undefined) int signed_right = b >> 2; // result depends on compiler (arithmetic vs logical shift) printf("Safe left shift: %u\n", safe_left); printf("Safe right shift: %u\n", safe_right); printf("Unsafe left shift (may be undefined): %u\n", unsafe_left); printf("Signed right shift (may be undefined or implementation-defined): %d\n", signed_right); return 0; }

To ensure your shift operations are portable and robust, always follow these guidelines:

  • Always use a non-negative shift amount less than the width (in bits) of the operand's type;
  • Prefer shifting unsigned integers, as shifting signed values—especially negative ones—can be undefined or implementation-defined;
  • Avoid shifting by a variable unless you have checked that the value is within a safe range;
  • Use constants or perform explicit checks before shifting to guarantee safety;
  • Be aware that right shifting negative signed integers may not behave the same on all platforms;
  • Never shift by the size of the type or more, as this is always undefined behavior;
  • Document your assumptions about operand sizes and shift amounts for future maintainability. By following these practices, you can write C code that manipulates bits safely, predictably, and portably across compilers and platforms.
question mark

Which practice helps you avoid undefined behavior when using bit shifts in C?

Select the correct answer

Oliko kaikki selvää?

Miten voimme parantaa sitä?

Kiitos palautteestasi!

Osio 2. Luku 4

Kysy tekoälyä

expand

Kysy tekoälyä

ChatGPT

Kysy mitä tahansa tai kokeile jotakin ehdotetuista kysymyksistä aloittaaksesi keskustelumme

bookSafe Shifting Rules

Pyyhkäise näyttääksesi valikon

Bit shifting in C can cause undefined behavior if used incorrectly, leading to crashes or inconsistent results across compilers. Avoid shifting by negative values, shifting by an amount greater than or equal to the bit width, and shifting negative numbers, especially with right shifts. These mistakes break portability and program safety.

safe_unsafe_shifts.c

safe_unsafe_shifts.c

copy
123456789101112131415161718192021222324252627282930
#include <stdio.h> #include <limits.h> int main() { unsigned int a = 1; int b = -8; int shift_amount = 32; // Safe left shift: within type width, unsigned type unsigned int safe_left = a << 3; // 1 shifted left by 3 is 8 // Safe right shift: unsigned type, within range unsigned int safe_right = a >> 1; // 1 shifted right by 1 is 0 // Unsafe left shift: shift amount >= type width (undefined behavior) unsigned int unsafe_left = a << shift_amount; // undefined if shift_amount >= 32 // Unsafe right shift: negative shift amount (undefined behavior) // unsigned int unsafe_right = a >> -1; // Uncommenting this is always undefined // Unsafe right shift: signed negative value (implementation-defined or undefined) int signed_right = b >> 2; // result depends on compiler (arithmetic vs logical shift) printf("Safe left shift: %u\n", safe_left); printf("Safe right shift: %u\n", safe_right); printf("Unsafe left shift (may be undefined): %u\n", unsafe_left); printf("Signed right shift (may be undefined or implementation-defined): %d\n", signed_right); return 0; }

To ensure your shift operations are portable and robust, always follow these guidelines:

  • Always use a non-negative shift amount less than the width (in bits) of the operand's type;
  • Prefer shifting unsigned integers, as shifting signed values—especially negative ones—can be undefined or implementation-defined;
  • Avoid shifting by a variable unless you have checked that the value is within a safe range;
  • Use constants or perform explicit checks before shifting to guarantee safety;
  • Be aware that right shifting negative signed integers may not behave the same on all platforms;
  • Never shift by the size of the type or more, as this is always undefined behavior;
  • Document your assumptions about operand sizes and shift amounts for future maintainability. By following these practices, you can write C code that manipulates bits safely, predictably, and portably across compilers and platforms.
question mark

Which practice helps you avoid undefined behavior when using bit shifts in C?

Select the correct answer

Oliko kaikki selvää?

Miten voimme parantaa sitä?

Kiitos palautteestasi!

Osio 2. Luku 4
some-alt