Introduction
The purpose of this article is to document a special case that is not otherwise documented, so far as I know, where a preprocessor error gets past the preprocessor because it doesn't recognize the line as one for it to process, causing a C2143 error diagnostic on the next line that isn't either comment or whitespace.
Background
I am developing a table driven routine to fill a NUMBERFMT
structure that another routine will use to format integers per the number format settings in the Regional Settings section of the Windows Control Panel. This is a complete rewrite of one of the first utility functions I wrote in C, in 2005. (I had dabbled in C before that, but I didn't get serious about it until then.) Since the routine processes integers exclusively, the NumDigits
member of that structure is overridden.
Using the Code
Consider the following opening guard block such as you should put at the top of your C and C++ headers.
#if !defined ( COMMONWINDOWSTYPES_INCLUDED )
#define COMMONWINDOWSTYPES_INCLUDED
Now, consider that a fat finger gives you this:
#if !defined ( COMMONWINDOWSTYPES_INCLUDED )
COMMONWINDOWSTYPES_INCLUDED
Following the foregoing, you have the following:
#if defined ( _MSC_VER ) && ( _MSC_VER >= 1020 )
#pragma once
#endif /* #if defined ( _MSC_VER ) && ( _MSC_VER >= 1020 ) */
typedef enum _tagCommonWindowsTypes {
When it encounters the last line shown above, typedef enum _tagCommonWindowsTypes
, the compiler emits error C2143, and the compilation fails. Compiler Error C2143, "syntax error : missing 'token1' before 'token2'" gives few clues, and the unusually abundant examples cited apply primarily to C++ translations, and those that apply as well to C translations call attention to things like missing semicolons and type declarations.
The most useful clue was the following:
Quote:
C2143 can occur when a closing brace, parenthesis, or semicolon is missing on the line where the error is detected or on one of the lines just above.
While the suggestion above didn't solve the problem, it prodded me to scroll upwards in the header, where the syntax error that actually gave rise to the problem jumped out at me, in the second line, where the guard block named a guard symbol, but neglected the keyword (#define
) that told the C preprocessor to eat it.
Points of Interest
C preprocessor errors are among the most elusive to identify and correct, and I have noticed that other errors can mask them, by which I mean that they sometimes won't show up until other errors are cleared. Before this error surfaced, I had compiled FormatLongIntW.C, one of two source files that includes CommonWindowsTypes.H, via the context menu in the Solution Explorer, which initially flagged several errors that were the result of last minute changes in another header to replace about a dozen #define
constants with two enumerations. The C2143 error didn't appear until the other errors (undefined symbols) were cleared.
History
- Sunday, 17th July 2016: Article submitted for publication