Visual C++ Compiler Fatal Error C1903

Message Text

unable to recover from previous error(s); stopping compilation

Circumstances

The compiler typically attempts some sort of continuation after an error, and it is not the policy of these notes ever to criticise (or even bring to attention) any quirks in the compiler’s sometimes valiant attempts at such continuation. In some cases, the compiler declines to try continuing, even though the error would ideally not be fatal. The visible result is fatal error C1903. It may be that something unusual is noticed about the circumstances, such that the error is ordinarily not fatal but in these circumstances is too difficult and is instead declared fatal. It may just be that the error is always fatal in practice because although the compiler’s writers have not defined a fatal error number for it, and might not want to, neither have they yet got round to writing code for any continuation.

One error for which the front-end C++ compiler presently provides no continuation in any circumstances is C2687. To generate this error, ignore everything that the product documentation says about it, and instead attempt an out-of-line definition of a class that is nested in a template class, e.g.,

template <typename T> class Test
{
    class Nested;
};

template <typename T> class Test <int> :: Nested        // C2687 and C1903
{
};

One case is known where fatal error C1903 is the one and only message given to the user, who may then puzzle over the “previous error(s)” that are never described. To observe, compile the one-line source file:

#import <rubbish> ptrsize (0)

CPU Exceptions

Fatal error C1903 can also occur in response to a CPU exception. If there has already been an error during compilation, no matter how long before and how well recovered, then a CPU exception that would ordinarily be reported as an internal compiler error C1001, specifically in the case that version 13.00.9466 attributes to

compiler file 'msc1.cpp', line 2844

is instead reported as fatal error C1903. The thinking is presumably that the compiler is continuing from an error and the CPU exception is an artifact of the continuation having been too bold. Though the exception is more or less by definition a coding error in the compiler, it may reasonably be forgiven and should be regarded as an internal compiler error only if it persists after the other errors have been fixed.

For example, compile the following with the /Zc:wchar_t option and without /Yu.

1;                              // C2059
#if _WCHAR_T_DEFINED            // C1903
#endif

The second line (indeed, any evaluation of the built-in macro _WCHAR_T_DEFINED) is known to trigger a coding error in the compiler. The first line is added just to contrive a previous error. Delete the first line, i.e., deal with the contrived error, to reveal that the C1903 is really a C1001.