Repository navigation
Fix #711 (#if true evaluates to false in C++ and C23) - #712
Conversation
dmcppcheck
left a comment
There was a problem hiding this comment.
AI review
I found no correctness problems for the cases the PR targets. With -std=c++11, c2x/c23 and c17, the new handling of true/false in #if matches gcc and clang, including macros that expand to true, #define true 0, defined(true), true + true == 2 and ternaries.
There is one behaviour difference to decide on. When dui.std is empty or not recognised, getCStd returns CUnknown, so true now evaluates to 1. A .c file run through the simplecpp tool without -std therefore takes the C++/C23 branch. gcc -E and clang -E (default gnu17) take the other branch. This only matters if callers leave std empty for C code. As far as I know cppcheck always sets std, so the main effect is on the command line tool. The new test asserts this default on purpose, so this may well be intended, but it is a change in behaviour for C input.
Testing
Build and test suites
make -j8 testrunner simplecpp CXXOPTS=-Werrorin pr/ built cleanly../testrunner: no failures.python3 run-tests.py: 176 tests, 0 failed (21 skipped, 16 todo, same as usual).pytest integration_test.py: 128 passed../selfcheck.sh: exit code 0.- I also built base/ to compare results.
Comparison with gcc 13 and clang 18
I wrote scratch/a.c with these conditions, numbered T1 to T8:
#if truedefined(true)false || 1#define true 0followed by#if true#define X truefollowed by#if Xtrue + true == 2(true ? 2 : 3) == 2__has_include(<stdio.h>) == true
| std | pr | base | gcc | clang |
|---|---|---|---|---|
| (none) | T1 T3 T5 T6 T7 | T3 T8 | T3 | T3 |
| c17 | T3 T8 | T3 T8 | T3 | T3 |
| c23 (gcc: c2x) | T1 T3 T5 T6 T7 | T3 T8 | T1 T3 T5 T6 T7 T8 | T1 T3 T5 T6 T7 T8 |
How to read the table:
- With c17 and c23, the PR matches gcc and clang. T8 is only missing because no include paths were given, so
__has_includeis 0. This is not related to the PR. - With no
-std, the PR differs from gcc and clang for this C file (/work/pr/simplecpp a.ccompared withgcc -E a.c). That difference is the one described in the summary.
Invalid expressions in C++
#if true(1) and #if true 2 now give no diagnostic, where gcc reports "missing binary operator". simplecpp already treats #if 1 2 the same silent way (the existing TODO: handle invalid expressions), so I am not reporting this as a problem of the PR.
Automated review of b17b484 by Claude. The pull request was built and tested locally.
No description provided.