1

I have the following errors reported when trying to build my application:

  • error C2143: syntax error : missing '}' before 'constant'
  • error C2143: syntax error : missing ';' before 'constant'
  • error C2059: syntax error : 'constant'

For the following code:

namespace oP
{
      enum adjustment
      {
         AUTO_OFF,
         AUTO_ONCE,
         AUTO_CONTINUOUS,
         AUTO_SEMI,
         ABSOLUTE,        // The line that the errors point to.
         NUDGE
      };
}

Lower case "absolute" builds ok, and if I misspell ABSOLUTE then it builds without errors.

I've searched my entire codebase and there's nowhere else using the term "ABSOLUTE". I've investigated the built artifact without this change and I can't find any reference to ABSOLUTE in it.

Does anyone have pointers as to what's wrong or how to debug this?

Thanks

James
  • 121
  • 1
  • 8
  • 1
    Which compiler are you using? – Sam Estep Jun 29 '15 at 12:45
  • 3
    You've a macro defined in that name somewhere in one of your included files probably. Check them; the easier way is to inspect the preprocessor's output. If you use `g++`, use the `-E` flag to stop after the preprocessing stage. – legends2k Jun 29 '15 at 12:47
  • 1
    I suspect some header (yours or 3rd party) has `ABSOLUTE` defined as `::fabs`. If it was part of the C++ standard library then that is a poor implementation. – Bathsheba Jun 29 '15 at 12:50
  • There is a #include of – James Jun 29 '15 at 12:51
  • 1
    @James Then you need to use `/E` or `/P`. See [here](http://stackoverflow.com/q/277258/183120). – legends2k Jun 29 '15 at 12:53

4 Answers4

6

ABSOLUTE is #defined (to the number 1) in one of the windows API headers <windi.h>. That is what is confusing the compiler.

You could #undef it, remove <windows.h> if you don't need it, or rename your enumeration.

Bathsheba
  • 231,907
  • 34
  • 361
  • 483
3

You've a macro defined in that name somewhere in one of your included files; check them. The easier way is to inspect the preprocessor's output.

If you use GCC, use the -E flag to stop after the preprocessing stage. With VC++ compiler you should be using /E and/or /P. See How do I see a C/C++ source file after preprocessing in Visual Studio? for details.


Usually the convention is to name macros in all uppercase; this is applicable to enumerations too, if you use C++03's (ordinary) enums. A better alternative is to use C++11's strongly-typed, scoped enumerations.

The name of each entry can be in Pascal case and with the enumeration's name decoration they become very readable Adjustment::Absolute as opposed to the older, unscoped enumeration's ABSOLUTE. This isn't very readable since the reader might confuse herself with the macro which wingdi.h declares (as Bathsheba points out). Apart from readability, it also avoids polluting the enclosing namespace.

Community
  • 1
  • 1
legends2k
  • 31,634
  • 25
  • 118
  • 222
  • "this is applicable to enumerations too" Not really. ALL_UPPER_CASE normally applies to macros, and constants defined through macros. Enumerations and normal constants can use normal naming convention. [See Qt 4/5 for examples](http://doc.qt.io/qt-5/qt.html). Also you can enclose enums within structs and namespaces, which is often very useful. – SigTerm Jun 29 '15 at 13:11
  • Even with the more strongly-typed scoped enumerations, wouldn't the preprocessor replace values in those with the macro definition? Currently it's referenced with oP::ABSOLUTE successfully anyway. – James Jun 29 '15 at 13:30
  • @SigTerm Of course, that's why it is a convention, not a set rule. But most code bases I've seen tended to use all caps for macros _and_ enums. It's a C-ism. – legends2k Jun 29 '15 at 13:36
  • @James Yes, even with scoped enumerations, the processor would just blinding replace `ABSOLUTE` with the actual constant the macro is named after. I can confirm this on both GCC 5.1.0 and VC++ 17.00.61030. – legends2k Jun 29 '15 at 13:42
  • @legends2k I think your comment on my question was a better answer to the general question than what you've put as your actual answer. – James Jul 01 '15 at 10:14
  • Updated the answer, should be fine now :) – legends2k Jul 01 '15 at 10:59
2

Your are using visual c++ compiler and #include then you should get this error. In windows.h the file #include < wingdi.h> is included and in wingdi.h you will find

/* Coordinate Modes */
#define ABSOLUTE            1
#define RELATIVE            2

Hence error occurred.

Santosh Dhanawade
  • 1,756
  • 14
  • 29
-1

How do I find something that the C++ compiler thinks is defined as a constant?

If your compiler is unwilling to produce helpful messages (usually it prints where term has been defined previously) or if you suspect that you fell victim of macro voodoo in WinAPI headers...

Selectively comment out lines of code and recompile to pinpoint the problem. If you comment out one line and your program compiles after that, that line is source of your problem. If your code block is big, do "binary search" - comment out a whole block, then half of it, so you narrow down the problem quickly.

In IDEs you often can mouse over the item to see where it is defined or press a key or use context menus to "jump to definition".

In addition to that you can investigate preprocessor output.


and can't selectively comment out headers to test when it changes - since the new list of compiler warnings would be too onerous to work through

Make a blank *.cpp file and copy the problematic definitions into it till you break it. That would allow you to pinpoint the problem.

It is a good practice to always include only the minimal set of necessary headers into your own *.h files, preferably completely avoiding OS-specific headers, although that is not really possible in this case.

In your particular scenario another good option is to change your naming style for enum values. Normally ALL_UPPERCASE is reserved for macros only (macros definition and macro constants). A notable exception to this rule is the min and max macros defined within Windows headers (they can be disabled). Because you used it in an enum, you clashed with OS-specific definition. I would use the same naming convention for enums as for constant and local variables.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
SigTerm
  • 26,089
  • 6
  • 66
  • 115
  • Those are some helpful heuristics, but they wouldn't have helped in this instance. I knew what line of code gave the problem, and can't selectively comment out headers to test when it changes - since the new list of compiler warnings would be too onerous to work through. Just tested in Visual Studio - it can't pick up that ABSOLUTE's also defined in a header file. – James Jun 29 '15 at 15:17
  • 1
    @James: Last paragraphs apply to this case. Aside from IDE help you can't really know where symbol is defined. Also, you can comment out headers. Copy-paste problematic declaration into blank *.cpp file and start adding headers till you break it. – SigTerm Jun 29 '15 at 15:20