#include <stdio.h>
#include <stdint.h>
//macros
#define SET_BIT(reg,bit) ((reg) |= (1U << (bit)))
#define CLEAR_BIT(reg,bit) ((reg) &= ~(1U << (bit)))
#define TOGGLE_BIT(reg,bit) ((reg) ^= (1U << (bit)))
uint8_t modify_register(uint8_t reg) {
SET_BIT(reg,2);
SET_BIT(reg,7);
CLEAR_BIT(reg,3);
TOGGLE_BIT(reg,5);
return reg;
}
int main() {
uint8_t reg;
scanf("%hhu", ®);
printf("%u", modify_register(reg));
return 0;
}Perfect 🔥
Let’s explain this clearly and professionally — like in an interview.
We’ll go in this order:
1️⃣ Macro-Based Version (SET_BIT, CLEAR_BIT, TOGGLE_BIT)
2️⃣ Alternate Reusable BIT(n) Version
#define SET_BIT(reg,bit) ((reg) |= (1U << (bit)))
#define CLEAR_BIT(reg,bit) ((reg) &= ~(1U << (bit)))
#define TOGGLE_BIT(reg,bit) ((reg) ^= (1U << (bit)))
uint8_t modify_register(uint8_t reg) {
SET_BIT(reg, 2);
SET_BIT(reg, 7);
CLEAR_BIT(reg, 3);
TOGGLE_BIT(reg, 5);
return reg;
}
Here, we define operation-specific macros.
Each macro directly represents one hardware action:
| Macro | Meaning |
|---|---|
| SET_BIT | Force bit to 1 |
| CLEAR_BIT | Force bit to 0 |
| TOGGLE_BIT | Flip the bit |
Example:
#define SET_BIT(reg,bit) ((reg) |= (1U << (bit)))
1U << bitCreates mask:
If bit = 5:
00000001 << 5
=
00100000
reg |= mask
OR forces that bit to 1.
✔ Very readable
✔ Clear intention
✔ Easy for beginners
✔ Explicit operation
✔ Matches hardware documentation
Example (STM32 style):
SET_BIT(GPIOA->ODR, 5);
Looks clean and expressive.
((reg) |= (1U << (bit)))
Parentheses prevent macro expansion bugs when passing expressions.
Now let’s look at this cleaner abstraction:
#define BIT(n) (1U << (n))
uint8_t modify_register(uint8_t reg) {
reg |= BIT(2) | BIT(7); // Set bits
reg &= ~BIT(3); // Clear bit
reg ^= BIT(5); // Toggle bit
return reg;
}
Instead of defining 3 operation macros, we define only:
#define BIT(n) (1U << (n))
Now we manually use operators:
|= → Set&= ~ → Clear^= → ToggleBecause:
Example:
reg |= BIT(2) | BIT(7);
You set two bits in one line.
With operation macros, you'd need two lines.
| Feature | Operation Macros | BIT(n) Version |
|---|---|---|
| Beginner Friendly | ✅ Yes | Medium |
| Less Code | ❌ Slightly more | ✅ Less |
| More Flexible | Medium | ✅ High |
| Industry Style | Good | ⭐ Excellent |
| Easier Multi-bit | ❌ No | ✅ Yes |
Professional embedded code usually prefers:
#define BIT(n) (1U << (n))
Because:
If interviewer asks:
Which version would you prefer?
Strong answer:
I prefer the BIT(n) abstraction because it reduces macro duplication and allows flexible mask combinations, especially when configuring multi-bit registers.
That’s a solid embedded answer 🔥
Operation Macros → Educational, explicit
BIT(n) Version → Cleaner, scalable, production-style
Input
0
Expected Output
164