Skip to content

Fix #711 (#if true evaluates to false in C++ and C23) - #712

Merged
danmar merged 1 commit into
masterfrom
if-true-false
Nov 5, 2026
Merged

danmar merged 1 commit into
masterfrom
if-true-false

Conversation

@danmar

@danmar danmar commented Nov 4, 2026

Copy link
Copy Markdown
Collaborator

No description provided.

@dmcppcheck dmcppcheck left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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=-Werror in 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 true
  • defined(true)
  • false || 1
  • #define true 0 followed by #if true
  • #define X true followed by #if X
  • true + 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_include is 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.c compared with gcc -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.

Comment thread simplecpp.cpp Resolved
@danmar
danmar merged commit d5e6da6 into master Nov 5, 2026
73 of 75 checks passed
@danmar
danmar deleted the if-true-false branch November 5, 2026 08:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants