I started a new VCL application under C++Builder, and I observe something bizarre.
When I declare a const
member named DELETE
as std::string
, I get an error.
Here is the .h
file:
#pragma once
#ifndef Communication_ButtonTagH
#define Communication_ButtonTagH
#include <string>
namespace OverB::Communication
{
class ButtonTag
{
public:
static const std::wstring DELETE;
};
}
#endif
And here is the .cpp
file:
#include "Communication_ButtonTag.h"
namespace OverB::Communication
{
const std::wstring ButtonTag::DELETE = L"DELETE";
}
Changing only the name of the const
, the application builds correctly.
I am using C++Builder 11.1 Alexandria, and Windows 11.
Here is the list of errors:
[C++ Error] Communication_ButtonTag.h(13, 32): expected member name or ';' after declaration specifiers
[C++ Error] Communication_ButtonTag.h(13, 32): expected ')'
[C++ Error] Communication_ButtonTag.h(13, 32): to match this '('
[C++ Error] Communication_ButtonTag.cpp(5, 35): expected unqualified-id
Can anyone explain what is happening exactly?
The VCL is built on top of the Win32 API, which has a DELETE
preprocessor macro defined in winnt.h
:
#define DELETE (0x00010000L)
The preprocessor is run first, and it performs text replacements of defined macros before the compiler is run. Thus, after the preprocessor has processed your code and made its replacements, the compiler will see the following invalid code, which is why it errors:
#pragma once
#ifndef Communication_ButtonTagH
#define Communication_ButtonTagH
#include <string>
namespace OverB::Communication
{
class ButtonTag
{
public:
static const std::wstring (0x00010000L);
};
}
#endif
#include "Communication_ButtonTag.h"
namespace OverB::Communication
{
const std::wstring ButtonTag::(0x00010000L) = L"DELETE";
}
In short, don't declare your own variables and identifiers that happen to match the names of Win32 API macros. The Win32 API is primarily a C library, not a C++ library. It doesn't use properly typed constants, or respect namespaces, etc. Common C++ best practices go out the window when dealing with the Win32 SDK.