Skip to main content

How to Resolve Warning "CS0675: Bitwise-or operator used on a sign-extended operand" in C#

The Compiler Warning CS0675 is a logic safety warning regarding binary operations. The message reads: "Bitwise-or operator used on a sign-extended operand; consider casting to a smaller unsigned type first".

This warning occurs when you perform a Bitwise OR (|) operation on a signed variable (like sbyte, short, or int) that is being implicitly widened to a larger type (like int or long). If the variable is negative, C# preserves the sign by filling the new upper bits with 1s (Sign Extension). Using the OR operator with these extra 1s often corrupts the target variable by unintentionally overwriting existing data in the upper bits.

This guide explains how sign extension works and how to safely combine bits using unsigned casting.

Understanding Sign Extension

When a smaller signed integer is converted to a larger one (e.g., short to long), the value must remain mathematically equivalent.

  • Positive: short 5 (Binary ...000101) becomes long 5 (Binary 000...000101). Zeros are added.
  • Negative: short -1 (Binary ...111111) becomes long -1 (Binary 111...111111). Ones are added to preserve the negative value.

If you are doing math, this is good. If you are doing bitwise operations (treating the variable as a bag of bits), this is dangerous. The "1s" generated by the sign extension act like a flood, turning on bits in the destination that you intended to leave alone.

Scenario: Corrupting Data with Negative Values

Imagine you are packing data into a 64-bit long. You want to place a 16-bit value into the lower slot. If that 16-bit value happens to be negative (interpreted as a signed short), extending it to 64-bit fills the entire 64-bit variable with 1s, destroying whatever was already in the variable.

Example of Warning:

public void PackData()
{
// A 64-bit container with some data in the upper bits (0xAAAA...)
long container = 0xAAAAAAAA00000000;

// A 16-bit signed value (Binary: 1111 1111 1111 1011) representing -5
short part = -5;

// ⛔️ Warning CS0675: Bitwise-or operator used on a sign-extended operand.
// 1. 'part' is promoted to 'long'.
// 2. Because it is negative, it fills the upper 48 bits with '1's.
// 3. (0xAAAA...) | (0xFFFF...FFFB) results in (0xFFFF...FFFB).
// The original data in 'container' is wiped out.
long result = container | part;

Console.WriteLine($"Result Hex: {result:X}");
}

Output:

Result Hex: FFFFFFFFFFFFFFFB
note

Notice the As are gone. The result is corrupted.

Solution: Cast to Unsigned First

To fix this, you must tell the compiler: "Treat the bits in this variable strictly as bits, not as a negative number."

You achieve this by casting the smaller operand to its unsigned equivalent (byte, ushort, uint) before it gets promoted to the larger type. Unsigned types always Zero-Extend (fill upper bits with 0) when promoted.

Solution Cast short to ushort.

public void PackData()
{
long container = 0xAAAAAAAA00000000;
short part = -5;

// ✅ Correct:
// 1. (ushort)part treats the bits as the number 65531.
// 2. Promoting 65531 to 'long' pads with Zeros (0x0000...0000FFFB).
// 3. The OR operation now safely combines the bits.
long result = container | (ushort)part;

Console.WriteLine($"Result Hex: {result:X}");
}

Output:

Result Hex: AAAAAAAA0000FFFB
note

The original data A... is preserved, and the part is correctly placed in the lower bits.

note

Why not cast to int? If you cast (int)part, you are still casting to a signed type. If part is negative, (int)part is still negative, and the sign extension still happens when it goes to long. You must cast to an unsigned type (ushort or uint) to stop the sign extension.

Conclusion

CS0675 saves you from accidentally wiping out data bits.

  1. Understand the Operation: | (OR) is usually for combining bit flags or packing data.
  2. Identify the Risk: If the operand is signed and negative, it brings "baggage" (extra 1s) when promoted to a larger size.
  3. The Fix: Cast the operand to a specific unsigned type (e.g., (byte), (ushort), (uint)) before applying the bitwise operator.