Bird
Raised Fist0
Embedded Cprogramming~20 mins

Volatile keyword and why it matters in Embedded C - Practice Problems & Coding Challenges

Choose your learning style10 modes available
Challenge - 5 Problems
🎖️
Volatile Mastery
Get all challenges correct to earn this badge!
Test your skills under time pressure!
❓ Predict Output
intermediate
2:00remaining
What is the output of this code using volatile?
Consider the following embedded C code snippet. What will be the output printed by the program?
Embedded C
#include <stdio.h>

volatile int flag = 0;

void setFlag() {
    flag = 1;
}

int main() {
    while(flag == 0) {
        // waiting for flag to change
    }
    printf("Flag changed!\n");
    return 0;
}

// Assume setFlag() is called asynchronously by an interrupt or another thread.
AThe program crashes with a segmentation fault.
BThe program runs forever and never prints anything.
CThe program prints "Flag changed!" multiple times.
DThe program prints "Flag changed!" and exits.
Attempts:
2 left
💡 Hint
Think about how the volatile keyword affects compiler optimizations and variable visibility.
❓ Predict Output
intermediate
2:00remaining
What happens if volatile is removed?
Given the same code as before but without the volatile keyword on 'flag', what is the most likely behavior?
Embedded C
#include <stdio.h>

int flag = 0;

void setFlag() {
    flag = 1;
}

int main() {
    while(flag == 0) {
        // waiting for flag to change
    }
    printf("Flag changed!\n");
    return 0;
}

// Assume setFlag() is called asynchronously by an interrupt or another thread.
AThe program prints "Flag changed!" and exits.
BThe program prints "Flag changed!" multiple times.
CThe program runs forever and never prints anything.
DThe program crashes with a segmentation fault.
Attempts:
2 left
💡 Hint
Consider how the compiler might optimize the loop without volatile.
🔧 Debug
advanced
2:00remaining
Identify the problem with this volatile usage
What is the main issue with the following code snippet regarding volatile usage?
Embedded C
volatile int *ptr = (volatile int *)0x40000000;

int main() {
    *ptr = 5;
    int val = *ptr;
    if(val == 5) {
        // do something
    }
    return 0;
}
AThe data pointed to is volatile but the pointer is not volatile, which is correct.
BThe pointer and the data it points to should both be volatile.
CThe pointer is volatile but the data it points to is not volatile.
DThe pointer itself should be volatile, not the data it points to.
Attempts:
2 left
💡 Hint
Think about what volatile means for pointers and the data they point to.
📝 Syntax
advanced
2:00remaining
Which declaration correctly uses volatile for a hardware register?
Choose the correct declaration for a volatile pointer to a 32-bit hardware register at address 0x40001000.
Avolatile int *reg = (volatile int *)0x40001000;
Bint volatile *reg = (int volatile *)0x40001000;
Cint * volatile reg = (int *)0x40001000;
Dvolatile int volatile *reg = (volatile int volatile *)0x40001000;
Attempts:
2 left
💡 Hint
Remember that 'volatile' can appear before or after the type and applies to the pointed data.
🚀 Application
expert
3:00remaining
Why is volatile critical in embedded interrupt handling?
In embedded systems, why is it important to declare variables shared between main code and interrupt service routines (ISRs) as volatile?
ABecause volatile prevents the compiler from optimizing away reads and writes, ensuring the main code sees changes made by the ISR.
BBecause volatile makes the variable thread-safe and automatically locks it during ISR execution.
CBecause volatile increases the speed of variable access in ISRs.
DBecause volatile allows the variable to be stored in faster CPU registers.
Attempts:
2 left
💡 Hint
Think about how the compiler treats variables that can change unexpectedly.

Practice

(1/5)
1. What does the volatile keyword tell the compiler about a variable?
easy
A. The variable is stored in a register for faster access
B. The variable is constant and never changes
C. The variable is only used inside a function
D. The variable can change at any time outside the program flow

Solution

  1. Step 1: Understand the role of volatile

    The volatile keyword tells the compiler that the variable's value can change unexpectedly, such as by hardware or interrupts.
  2. Step 2: Identify what this means for the compiler

    The compiler must not optimize away reads or writes to this variable because its value can change outside normal program flow.
  3. Final Answer:

    The variable can change at any time outside the program flow -> Option D
  4. Quick Check:

    volatile means variable changes anytime [OK]
Hint: Volatile means variable can change anytime outside code [OK]
Common Mistakes:
  • Thinking volatile means variable is constant
  • Assuming volatile stores variable in register
  • Confusing volatile with static or const
2. Which of the following is the correct syntax to declare a volatile integer variable named flag?
easy
A. int volatile flag;
B. volatile int flag;
C. Both A and B are correct
D. int flag volatile;

Solution

  1. Step 1: Recall volatile declaration syntax

    In C, volatile can appear before or after the type specifier, so both volatile int flag; and int volatile flag; are valid.
  2. Step 2: Check each option

    int volatile flag; and volatile int flag; are both correct syntax. int flag volatile; is invalid because volatile must come before or immediately after the type, not after the variable name.
  3. Final Answer:

    Both A and B are correct -> Option C
  4. Quick Check:

    Volatile can be before or after type [OK]
Hint: Volatile can be before or after type keyword [OK]
Common Mistakes:
  • Placing volatile after variable name
  • Using volatile without type
  • Confusing volatile with const syntax
3. Consider this code snippet:
volatile int flag = 0;

void loop() {
  while(flag == 0) {
    // wait
  }
  // do something
}

What happens if flag is not declared volatile and is changed by an interrupt?
medium
A. The loop may never end because compiler optimizes flag check
B. The loop ends immediately as expected
C. Compilation error due to missing volatile
D. The program crashes

Solution

  1. Step 1: Understand compiler optimization without volatile

    If flag is not volatile, the compiler may assume it does not change inside the loop and optimize by reading it once.
  2. Step 2: Effect on loop behavior

    Because the compiler caches the value, changes made by interrupts to flag may be ignored, causing the loop to never end.
  3. Final Answer:

    The loop may never end because compiler optimizes flag check -> Option A
  4. Quick Check:

    Without volatile, compiler may cache variable [OK]
Hint: Without volatile, compiler may cache variable causing infinite loop [OK]
Common Mistakes:
  • Thinking code will always work without volatile
  • Assuming volatile causes compilation errors
  • Believing volatile slows down program always
4. Identify the problem in this code snippet:
int data_ready = 0;

void ISR() {
  data_ready = 1;
}

void main_loop() {
  while(data_ready == 0) {
    // wait
  }
  // process data
}

How to fix it?
medium
A. Declare data_ready as volatile int data_ready = 0;
B. Make data_ready a global constant
C. Remove the while loop
D. Declare data_ready as static int data_ready = 0;

Solution

  1. Step 1: Identify variable shared with ISR

    data_ready is changed inside an interrupt service routine (ISR) and read in main loop.
  2. Step 2: Understand why volatile is needed

    Without volatile, compiler may optimize and cache data_ready, ignoring changes from ISR.
  3. Step 3: Fix by declaring volatile

    Declaring volatile int data_ready = 0; tells compiler to always read fresh value.
  4. Final Answer:

    Declare data_ready as volatile int data_ready = 0; -> Option A
  5. Quick Check:

    Shared ISR variables must be volatile [OK]
Hint: Make ISR-shared variables volatile to avoid caching [OK]
Common Mistakes:
  • Using static instead of volatile
  • Removing loop without fixing variable
  • Making variable constant incorrectly
5. You have a hardware register at address 0x4000 that changes asynchronously. Which declaration ensures safe access to this register in embedded C?
hard
A. int *reg = (int *)0x4000;
B. volatile int *reg = (int *)0x4000;
C. const int *reg = (int *)0x4000;
D. static int *reg = (int *)0x4000;

Solution

  1. Step 1: Understand hardware register behavior

    Hardware registers can change anytime outside program control, so compiler must not optimize access.
  2. Step 2: Choose correct pointer declaration

    Declaring pointer as volatile int * tells compiler to always read/write actual memory, not cached value.
  3. Step 3: Evaluate options

    int *reg = (int *)0x4000; lacks volatile, risking optimization. const int *reg = (int *)0x4000; makes it constant, disallowing writes. static int *reg = (int *)0x4000; uses static incorrectly.
  4. Final Answer:

    volatile int *reg = (int *)0x4000; -> Option B
  5. Quick Check:

    Hardware registers need volatile pointers [OK]
Hint: Use volatile pointer for hardware registers [OK]
Common Mistakes:
  • Omitting volatile causing stale reads
  • Using const preventing writes
  • Confusing static with volatile
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard