Cant use enum DELETE in my Code, although its used inside a class

97 views Asked by At

I am writing a small QT app and have chosen spdlog to write my logfiles. I have isolated the problem enough to solve it, but I would like to know why this is happening.

I can't use the enum DELETE. See the following code snippets:

logger.h

#ifndef LOGGER_H
#define LOGGER_H

#include <memory>
#include <unordered_map>
#include <spdlog/spdlog.h>
#include <spdlog/sinks/stdout_color_sinks.h>
#include <spdlog/sinks/rotating_file_sink.h>
#include <spdlog/sinks/qt_sinks.h>
#include <spdlog/async.h>

...
..
.
#endif // LOGGER_H

databasemanager.h

#ifndef DATABASEMANAGER_H
#define DATABASEMANAGER_H
//#include logger.h

...include Stuff...

class DatabaseManager : public QObject
{

public:

    enum Action { SAVE , DELETE };

...more Stuff....

}
#endif // DATABASEMANAGER_H

Everything is fine, until I include logger.h in databasemanager.h or any other header/source file. Sometimes I get dozens of compiler errors.

The use of DatabaseManager::SAVE is fine, but I cant use DatabaseManager::DELETE.

One of the included Headers includes winnt.h, wich has the Line

#define DELETE (__MSABI_LONG(0x00010000))

compile error:

C:\Users\SB\OneDrive\Cpp\Projekte\_testprojekte\test\test\mainwindow.cpp:13: Fehler: expected identifier before '(' token
In file included from C:/Qt/Tools/mingw1120_64/x86_64-w64-mingw32/include/minwindef.h:163,
                 from C:/Qt/Tools/mingw1120_64/x86_64-w64-mingw32/include/windef.h:9,
                 from C:/Qt/Tools/mingw1120_64/x86_64-w64-mingw32/include/windows.h:69,
                 from ../test/spdlog/details/windows_include.h:11,
                 from ../test/spdlog/details/os-inl.h:25,
                 from ../test/spdlog/details/os.h:122,
                 from ../test/spdlog/details/log_msg-inl.h:10,
                 from ../test/spdlog/details/log_msg.h:39,
                 from ../test/spdlog/details/log_msg_buffer.h:6,
                 from ../test/spdlog/details/backtracer.h:7,
                 from ../test/spdlog/logger.h:18,
                 from ../test/spdlog/details/registry-inl.h:12,
                 from ../test/spdlog/details/registry.h:121,
                 from ../test/spdlog/spdlog.h:13,
                 from ..\test\logger.h:6,
                 from ..\test\mainwindow.cpp:3:
..\test\mainwindow.cpp: In constructor 'MainWindow::MainWindow(QWidget*)':
..\test\mainwindow.cpp:13:35: error: expected identifier before '(' token
   13 |     enum Databasemanager { SAVE , DELETE }
      |                                   ^~~~~~

I think that's the cause. But why? I use the enums in a class/namespace. Nevertheless, the DEFINE seems to overwrite the enum

2

There are 2 answers

1
perivesta On

This is indeed caused by a Windows header defining DELETE as a preprocessor macro. And since macros are only text replacements, they are unaffected by scope.

To get around this, you can #undef DELETE after you include your headers. Since you're using Qt, this could look like this:

#include <QtGlobal>
#ifdef Q_OS_WIN
#undef DELETE
#endif //Q_OS_WIN

You can also put this code in a separate header file and include that as the last include in your code. This allows you to add more #undef lines in the future (like near which is also a commonly used word that's defined in a Windows header).

Alternatively, you can of course just rename your enum value to not be all uppercase.

0
drescherjm On

You could also prefix your names of your enumerators for example instead of DELETE call it AC_DELETE:
enum Action { AC_SAVE , AC_DELETE };

Full example:

#include <iostream>
 
#define DELETE 42
  
class DatabaseManager 
{
public:
     enum Action { AC_SAVE , AC_DELETE };
     // More code here
};
  
int main() {
 
    DatabaseManager::Action act{DatabaseManager::AC_DELETE};
 
    if (act != DatabaseManager::AC_SAVE ) {
        std::cout << "It works!";
    }
 
    return 0;
}

I put this example online here: https://ideone.com/vdxSWf