Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / C

Sparsely Documented Cause of Compiler Error C2143

4.82/5 (6 votes)
17 Jul 2016CPOL2 min read 9K  
Sparsely documented cause of compiler error C2143

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.

C++
#if !defined ( COMMONWINDOWSTYPES_INCLUDED )
#define        COMMONWINDOWSTYPES_INCLUDED

Now, consider that a fat finger gives you this:

C++
#if !defined ( COMMONWINDOWSTYPES_INCLUDED )
               COMMONWINDOWSTYPES_INCLUDED

Following the foregoing, you have the following:

C++
/*
    ============================================================================

    Name:               CommonWindowsTypes.H

    Synopsis:           Library include to define constants for use in lookup
                        tables for driving processes that make decisions based
                        on the type of data stored in another column of the same
                        table.

    Example:            Consider a table of two columns.

                        1)  Column 1 consists of DWORDs that contain a mixture
                            of 32 bit signed integers and pointers to memory
                            locations.

                        2)  Column 2 contains values taken from this table that
                            indicate the type of data stored in column 1.

                        Column 2 could be sized in WORDs, if space is the only
                        consideration. However, if performance trumps size, as
                        most likely it does, considering the expected small size
                        of the table, it should also be DWORDs.

    Remarks:            The macros defined herein were created by copying the
                        contents of the last column of the last column in worksheet
                        Windows Data Types of Windows_and_C++_Data_Type_Tables.XLSX.
                        Its creation was motivated by a desire to replace a lot of
                        repetitive code that calls the same Windows API routine
                        with different parameters and destinations, along with a
                        side task or two. This is at least the second table of
                        this type that I have needed over the last year or so,
                        and I decided that I may as well define a set of standard
                        symbolic constants for such applications.

    References:         C:\Users\DAVE\OneDrive\REFERENCE\_QuickRef\Windows_and_C++_Data_Type_Tables.XLSX

    Date Written:       Friday, 15 July 2016

    License:            Copyright (C) 2016, David A. Gray. All rights reserved.

    Redistribution and use in source and binary forms, with or without
    modification, are permitted provided that the following conditions are met:

    *   Redistributions of source code must retain the above copyright notice,
    this list of conditions and the following disclaimer.

    *   Redistributions in binary form must reproduce the above copyright
    notice, this list of conditions and the following disclaimer in the
    documentation and/or other materials provided with the distribution.

    *   Neither the name of David A. Gray nor the names of his contributors may
    be used to endorse or promote products derived from this software without
    specific prior written permission.

    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
    ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
    THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

    ----------------------------------------------------------------------------
    Revision History
    ----------------------------------------------------------------------------

    Date       Author Synopsis
    ---------- ------ ----------------------------------------------------------
    2016/07/15 DAG    Initial, limited release.
    ============================================================================
*/

#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

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)