[ Resolved by issue 2518, adopted in February, 2023. ]
C99 is very clear that a #error directive causes a translation to fail: Clause 4 paragraph 4 says,
The implementation shall not successfully translate a preprocessing translation unit containing a #error preprocessing directive unless it is part of a group skipped by conditional inclusion.
C++, on the other hand, simply says that a #error directive “renders the program ill-formed” (15.8 [cpp.error]), and the only requirement for an ill-formed program is that a diagnostic be issued; the translation may continue and succeed. (Noted in passing: if this difference between C99 and C++ is addressed, it would be helpful for synchronization purposes in other contexts as well to introduce the term “preprocessing translation unit.”)
See also issue 2518.