COMP10002 Foundations of Algorithms
Checking And Debugging Your C Code
Practical commands for compiling with strong warnings, checking your code for bugs, and using tools that help you catch mistakes before submission.
Baseline build
Work from the directory that contains your own a1.c.
The safest starting point is to compile with the same warning level and language mode used by the assignment:
clang -Wall -Wextra -Wno-newline-eof -Wno-unused-parameter \
-pedantic -std=c17 -o a1 a1.c -lm
This is a good default because it is close to what the autograder expects. If your code does not compile cleanly here, fix that first.
Why first-year students should use these tools
If you are new to C, these tools are helpful because many C mistakes do not produce neat, obvious error messages.
A compiler might reject your code completely, but it can also accept code that still has a bug in it. Extra warnings , static analysis , and sanitizers give you more chances to catch problems early.
That matters in first year because:
- small syntax or type mistakes are easier to fix when the compiler points at them directly
- array and loop bugs are common in early C programs
- C is less forgiving than Python, so some mistakes compile but behave badly at runtime
- learning to use tools is part of learning to program, not an optional extra
For this assignment, these tools are especially useful for finding:
- wrong format strings in
printforscanf -
suspicious loop bounds
- accidental type conversions
- out-of-bounds array access
- undefined behaviour such as invalid shifts or bad memory use
What “static analysis” means
When you compile a C program, the compiler already checks some things for you, such as syntax errors and some suspicious code patterns.
Static analysis means:
- a tool inspects your source code without running the program
- it tries to spot bugs, risky logic, or style problems
- it gives you warnings before you test on actual input
For this assignment, it helps to separate three kinds of tools:
Compiler warnings: messages fromclangorgccduring compilationStatic analyzers: tools such asclang --analyze,gcc -fanalyzer, orcppcheckthat inspect code paths more deeply
These tools are useful, but they are not magic. A warning may be a false alarm, and a clean report does not prove the program is correct.
Clang flags
If you want a stricter local Clang build, try:
clang -Wall -Wextra -Wshadow -Wconversion -Wdouble-promotion \
-Wformat=2 -Wstrict-prototypes -pedantic -std=c17 -o a1 a1.c -lm
These flags can help catch:
-
variable shadowing
-
implicit numeric conversions
- format-string mistakes
- missing or weak function declarations
While you are still filling in the scaffold, you may also see unused-parameter warnings from unfinished TODO functions. That is normal in incomplete code. Once the functions are implemented, many of those warnings disappear.
Not every warning here must be enabled for grading, but they are useful while cleaning up your code.
Clang also includes a built-in static analyzer:
clang --analyze -Wall -Wextra -pedantic -std=c17 a1.c
If it reports a possible null dereference , dead store , or suspicious path , inspect it carefully. Some reports are false positives , but many are worth fixing.
GCC flags
On Linux with a real GNU gcc, a comparable warning build is:
gcc -Wall -Wextra -Wshadow -Wconversion -Wformat=2 \
-Wstrict-prototypes -pedantic -std=c17 -o a1 a1.c -lm
Recent GCC versions also have an analyzer mode:
gcc -fanalyzer -Wall -Wextra -pedantic -std=c17 -o a1 a1.c -lm
Important note: on many macOS setups, gcc is actually Apple Clang in disguise. If gcc --version prints something like Apple clang, then -fanalyzer is not the GNU GCC analyzer and may not exist. In that case, use clang --analyze and cppcheck instead.
Checking tools
cppcheck
cppcheck is available in many lab or Homebrew-style environments and is installed in this local environment. A practical command is:
cppcheck --enable=warning,style,performance,portability \
--std=c17 --language=c --inline-suppr a1.c
If you want more detail, add:
cppcheck --enable=all --std=c17 --language=c --inline-suppr a1.c
cppcheck is especially useful for:
-
suspicious conditions
-
uninitialised variables
-
unreachable branches
-
portability warnings
It can also be noisy, so treat it as a review tool, not an oracle.
Clang static analyzer
If you are using Clang, this is the simplest built-in static-analysis pass:
clang --analyze -Wall -Wextra -pedantic -std=c17 a1.c
This is path-sensitive , so it sometimes catches issues that ordinary warning flags miss.
Runtime tools
Strict warnings and static analysis help, but runtime tools catch a different class of bugs.
A sanitizer is a runtime checking tool. You compile your program with extra instrumentation, then run it normally. If something dangerous happens while the program is executing, the sanitizer tries to stop immediately and explain the problem.
The most useful sanitizers for this assignment are:
-fsanitize=addressfor out-of-bounds access, use-after-free , and related memory bugs-fsanitize=undefinedfor undefined behaviour such as bad shifts, signed overflow , or invalid pointer use-fsanitize=leakfor memory leaks, if your solution uses dynamic allocation
AddressSanitizer on its own is already very useful:
clang -g -fsanitize=address -fno-omit-frame-pointer \
-std=c17 -o a1-asan a1.c -lm
./a1-asan < test_data/test0.txt
If your program reads or writes outside an array, uses freed memory, or corrupts the stack, AddressSanitizer tends to gives a much better explanation than a normal crash.
A good general-purpose local debug build is:
clang -g -fsanitize=address,undefined -fno-omit-frame-pointer \
-std=c17 -o a1-sanitize a1.c -lm
./a1-sanitize < test_data/test0.txt
If you are using dynamic allocation and specifically want leak checking, you can also try:
clang -g -fsanitize=address,undefined,leak -fno-omit-frame-pointer \
-std=c17 -o a1-sanitize a1.c -lm
Suggested workflow
For this assignment, a sensible local checking loop is:
- Compile with the baseline assignment command.
- Recompile with a stricter warning set.
- Run
cppcheckif available. - Run
clang --analyzeif you are using Clang. - Run an AddressSanitizer build if something is crashing or behaving strangely.
No single tool is enough by itself. The goal is to combine fast compiler feedback, course-specific style checks, and at least one analyzer that looks for suspicious code paths.