-
Section 1: Getting Started
-
Section 2: Core Syntax
-
Section 3: Functions
-
Section 4: Arrays and Strings
-
Section 5: Pointers
-
Section 6: Memory Management
-
Section 7: Structures and Unions
-
Section 8: The Preprocessor and Build Process
-
Section 9: Standard Library: stdio.h
-
Section 10: Standard Library: stdlib.h
-
Section 11: Standard Library: string.h
-
Section 12: Standard Library: ctype.h and wctype.h
-
Section 13: Standard Library: math.h, complex.h, fenv.h, tgmath.h
-
Section 14: Standard Library: Type and Limit Headers
-
Section 15: Standard Library: Error Handling and Debugging
-
Section 16: Standard Library: Localization and Encoding
-
Section 17: Standard Library: time.h
-
Section 18: Standard Library: Concurrency (C11)
-
Section 19: POSIX and System Programming (unistd.h)
-
Section 20: More Data Structures
-
Section 21: Algorithms in C
-
Section 22: Bitwise Operations
-
Section 23: Command-Line Programs
-
Section 24: Debugging and Best Practices
-
Section 25: Compiler and Language Internals
-
Section 26: Embedded and Cross-Platform Considerations
-
Section 27: Networking Basics
-
Section 28: Practical Projects
-
Section 29: Interview Practice
-
Section 30: C23 Modern Features
-
Section 31: More Practice and Review
185: Practice Exercise: Building a Simple Bitmask-Based Flag System
I've seen this exact bug trip up plenty of developers—even some who've been coding for a while. You're trying to build a system to track various states for an object, like a player in a game or a configuration for a network socket, and you decide to use bitmasks because they're efficient. Then, you write your check, and suddenly, every single condition evaluates to true, regardless of which flags you actually set.
#define FLAG_READ (1 << 0) // 0001
#define FLAG_WRITE (1 << 1) // 0010
#define FLAG_EXECUTE (1 << 2) // 0100
unsigned char my_permissions = FLAG_READ;
if (my_permissions && FLAG_WRITE) {
printf("You have write access!\n");
}
The "Always True" Logical Check
In the snippet above, the programmer intended to check if the FLAG_WRITE bit was set. However, they used the logical AND operator (&&) instead of the bitwise AND operator (&). In C, && doesn't care about the individual bits; it only cares if the left side is non-zero (true) and the right side is non-zero (true).
Since my_permissions is 1 (true) and FLAG_WRITE is 2 (true), the condition evaluates to true. The code tells the user they have write access even though only the read bit was set. It's a subtle typo that creates a massive security hole or a logic nightmare.
Switching to Bitwise AND
To fix this, we need to isolate the specific bit we care about. By using &, we perform a bit-by-bit comparison. If the bit is not set in my_permissions, the result of the operation is 0, which C treats as false.
if (my_permissions & FLAG_WRITE) {
printf("You have write access!\n");
}
Now, 0001 & 0010 results in 0000. The condition fails, and the program behaves correctly. I always tell people to double-check their operators when working with flags; one extra & symbol changes the entire meaning of the line.
Managing State Transitions
Once you've got the checking part down, you need a reliable way to flip these flags on and off without disturbing the others. If you use simple assignment (=), you wipe out all other flags. If you use addition (+), you risk "carrying" a bit into the next position if the flag was already set, which corrupts your state.
Instead, use the bitwise OR (|) to set a flag and the bitwise AND with a NOT (& ~) to clear it. Here is the pattern I use in production code:
// Set the EXECUTE flag without touching READ or WRITE
my_permissions |= FLAG_EXECUTE;
// Clear the READ flag while leaving others intact
my_permissions &= ~FLAG_READ;
// Toggle the WRITE flag (on if off, off if on)
my_permissions ^= FLAG_WRITE;
Using ~FLAG_READ creates a mask where every bit is 1 except for the read bit. When you AND that with your permissions, the read bit is forced to 0, and everything else stays exactly as it was.
📋 Practical Task
Exercise: Building a Character Status Effect System
You are tasked with creating a status effect system for an RPG character. The character can be affected by several states: Poisoned, Stunned, Frozen, and Invisible.
Write a program that does the following:
- Define the four status effects using bit-shifts (e.g.,
1 << 0,1 << 1, etc.). - Create an
unsigned char statusvariable to track the current state. - Implement the following sequence of events:
- Set the character to be Poisoned and Invisible.
- Check if the character is Stunned (it should be false).
- Add the Stunned effect.
- Remove the Poisoned effect.
- Check if the character is Invisible (it should be true).
- Print the final status of each flag to the console to verify your work.
There are no comments for now.