Using Clang's -Wunused-variable to Detect Unused Declarations
Enable Clang's -Wunused-variable to catch declared‑but‑never‑read variables, see how Sema emits the diagnostic, and learn limits and silencing techniques.
26 Dec 2025, 02:35 UTC

Quick answer
Add -Wunused-variable to your Clang command line to get a warning whenever a variable is declared but never read. Promote it to an error with -Werror=unused-variable if you want the build to fail on the first occurrence.
How the warning works
After the parser builds an abstract syntax tree, Clang’s Sema (semantic analysis) phase walks the tree and tracks each variable’s uses. If a variable has no read‑access in its lifetime, Sema emits the -Wunused-variable diagnostic. The check respects C and C++ scope rules: a variable in an inner scope that shadows an outer name is considered used only if the inner name is referenced.
Worked example
/* test.c */
#include
int main(void) {
int used = 42; /* this variable is read */
int unused; /* never read → warning */
printf("%d\n", used);
return 0;
}
Compile with the warning enabled:
clang -Wall -Wunused-variable test.c -o test
Expected output (no invention):
test.c:6:5: warning: variable 'unused' set but not used [-Wunused-variable]
int unused;
^
1 warning generated.
To silence the warning intentionally, you can either cast to void or use the [[maybe_unused]] attribute (C++17):
[[maybe_unused]] int unused; /* no warning */
(void)unused; /* also silences */
Limits and common mistakes
- Delayed diagnostics in templates: If an unused variable appears inside a template that is never instantiated, Clang will not warn until the template is used. This can hide issues in header‑only libraries.
- False positives for future code: Variables deliberately left unused for later implementation trigger the warning. Silencing them with
[[maybe_unused]]or a void cast documents the intent. - Scope confusion: A variable named the same as an outer variable is considered used only when the inner name is referenced. Mistakenly referencing the outer name will still generate a warning for the inner declaration.
- Upgrade to error: Using
-Werror=unused-variableturns the warning into a hard error. Ensure your build system can handle the new failure mode before enabling it globally.
Practical verification
- Create a small source file with an unused variable.
- Run
clang -Wunused-variable <file>and confirm the warning appears. - Add
[[maybe_unused]]or a void cast and rebuild; the warning should disappear. - Re‑compile with
-Werror=unused-variableand verify the build fails.
These steps let you confirm that the diagnostic is active and that your silencing technique works as intended.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.