Author Topic: Help adding a static, compile time constant variable to a class/struct in C++  (Read 220 times)

Offline Vagabond

  • Sr. Member
  • ****
  • Posts: 337
Iím trying to add a private variable to a class that is constant at compile time and static (does not reside in an individual instance of the class.)

Unfortunately, I cannot get my code to compile. Below is roughly what Iím typing in.
 
Code: [Select]
class XFile
{

...

private:
constexpr static string notSupportedMessage("Operating system not supported.");
};
Iím getting error code E0079 Expected a Type Specifier.

I was hoping for some insight in how to properly format the code.

-Brett


Offline Sirbomber

  • Hero Member
  • *****
  • Posts: 3169
    • http://
String isn't a built-in type, so I don't think you can do what you're trying to do.  You can probably declare it as static and then define it elsewhere, though.  However, I also think your code is wrong for what you say you want to do - you say you want a variable, but isn't this defining a function named notSupportedMessage that returns a string and takes the argument "Operating system not supported."?
"As usual, colonist opinion is split between those who think the plague is a good idea, and those who are dying from it." - Outpost Evening Star

Outpost 2 Coding 101 Tutorials

"Outpost 2: The Campaigns Are Okay, But The Novella Just Flames Everyone" progress:
Campaign 1 - 40%
Campaign 2 - 0%
Etc. - (insert arbitrary value here)%

It could only cost you your life, and you got that for free!

Offline Vagabond

  • Sr. Member
  • ****
  • Posts: 337
Okay thanks for taking a look at it sirbomber.

I think my code should be calling the constructor on std::string and setting it to "Operating system not supported.". I think this weekend I should be able to put some more time into it.

Online Hooman

  • Administrator
  • Hero Member
  • *****
  • Posts: 3776
You declare static variables inside the class definition, but define static variables outside of the class definition.

Code: [Select]
// XFile.h
class XFile {
private:
  static string notSupportedMessage;
};

// XFile.cpp
string XFile::notSupportedMessage("Operating system not supported.");

Though, considering your message, I wonder if a compile time error might be more appropriate?

Offline Arklon

  • Administrator
  • Hero Member
  • *****
  • Posts: 1114
Yeah, this sounds like something you'd want to just use a static_assert for.

Offline Vagabond

  • Sr. Member
  • ****
  • Posts: 337
Thanks Hooman & Arklon,

I wasn't aware of the preprocessor directive #error, which works much better than throwing an error when the code executes in this case.

Thanks for the help!

-Brett

Online Hooman

  • Administrator
  • Hero Member
  • *****
  • Posts: 3776
Edit: Got sidetracked while composing this response. Seems you beat me to #error.

Using static_assert could work. You can also use #error.

Example:
Code: [Select]
#ifdef _WIN32
  // Windows specific code
#elif __linux__
  // Linux specific code
#else
  #error OS not supported
#endif

As per the linked documentation, it doesn't matter if the string after #error is quoted or not.

To use static_assert, instead of #error, it might look something like this:
Code: [Select]
static_assert(false, "OS not supported");

Note: You can't simple use preprocessor #defines such as _WIN32, or __linux__ directly with static_assert, since if they're not defined (normally checked by #ifdef/#ifndef), there is no symbol substitution, so the compiler will see an unknown symbol. Also, to get this to compile under Linux, the newer version of C++ must be explicitly enabled: g++ -std=c++11 cppError.cpp

Offline Arklon

  • Administrator
  • Hero Member
  • *****
  • Posts: 1114
The problem with #error is MSVC's syntax for it uses no quotes and GCC's syntax for it does.

Online Hooman

  • Administrator
  • Hero Member
  • *****
  • Posts: 3776
Do you have a reference for that? I just went looking to confirm, and couldn't find anything. I did however see a few GCC examples that didn't use quotes.

Admittedly, it looks way better with quotes.

Offline Vagabond

  • Sr. Member
  • ****
  • Posts: 337
Just tested on Visual Studio 2017. MSVC compiles and runs both with or without quotes. However, if you put quotes around the message, the error message will include the quotes. Ideally, the quotes wouldn't be there, but it compiles and gets the message across clearly.

If someone wants to test on GCC we could compare.

Code: [Select]
#if defined (linux)

    . . .

#else
#error "Operating system not supported."
#endif

Results
Code: [Select]
Error (active)	E0035	#error directive: "Operating system not supported." OP2Utility
Code: [Select]
Error	C1189	#error:  "Operating system not supported." OP2Utility

Online Hooman

  • Administrator
  • Hero Member
  • *****
  • Posts: 3776
Tested with GCC:
Code: [Select]
#error OS not supported

Result:
Code: [Select]
cppError.cpp:5:2: error: #error OS not supported
 #error OS not supported
  ^