5

Was looking at boost asio ssl_client.cpp example and found this right on the top:

enum { max_length = 1024 };

Wonder, is there any difference between this and

namespace {
    const int max_length = 1024;
}

or

static const int max_length = 1024;

Or maybe they are absolutely equal but this is just shorter?

VP.
  • 15,509
  • 17
  • 91
  • 161
  • 1
    I expect you mean typically interchangeable, not "absolutely equal". I'm sure a language lawyer can find many more differences, but I would start with `&max_length`. I assume you never use `&max_length`. For a class static, can the optimizer assume you never use `&max_length`. If not, does that make a class static const int less efficient than an enum? – JSF Nov 11 '15 at 14:30
  • Yes, JSF hits the right points. – sehe Nov 11 '15 at 14:32
  • http://stackoverflow.com/questions/899917/why-do-people-use-enums-in-c-as-constants-while-they-can-use-const – Sigcont Nov 11 '15 at 14:34
  • Please just don't close this as a dupe to that question. The votes are so misleading. – Karoly Horvath Nov 11 '15 at 14:44

2 Answers2

3

They're equivalent, if you use it for the value, not by reference.

The enum { constantname = initializer }; idiom used to be very popular in header files, so you could use it within a class declaration without problems:

struct X {
    enum { id = 1 };
};

Because with a static const member, you would need an out-of-class initializer and it couldn't be in the header file.

Update

Cool kids do this these days:

struct X {
    static constexpr int id = 1;
};

Or they go with Scott Meyer¹ and write:

struct X {
    static const int id = 1;
};

// later, in a cpp-file near you:
const int X::id;

int main() {
    int const* v = &X::id; // can use address!
}

¹ see Declaration-only integral static const and constexpr data members, Item #30

sehe
  • 374,641
  • 47
  • 450
  • 633
  • 2
    You say "used to be". Care to explain what the cool kids do now? – ams Nov 11 '15 at 16:47
  • @ams, I think the "cool kids" use constexpr and I think SO tries to explain some of that at http://stackoverflow.com/questions/11522399/constexpr-initializing-static-member-using-static-function but I would have hoped for a clearer explanation. – JSF Nov 11 '15 at 16:55
  • @ams Added the "cool kids way" for both flavours today! (Now with source reference) – sehe Nov 11 '15 at 17:04
  • Thanks. This explains a lot. – ams Nov 11 '15 at 17:07
  • So in the spirit of the original reasons the "non cool kids" used `enum`, if you **REALLY** really want to fully define it inside the header that defines the class (with nothing spilling over into a .cpp file) and you would prefer to **not** be able to use its address, am I correct that `static const int` still falls short of the original goals, but a `constexpr` can do the job? – JSF Nov 11 '15 at 17:37
  • @JSF I tend to use the non cool approach to stay clear of the gray area that Scott Meyer mentions (the standard seems to require the out of class definition for `constexpr` static class members though some compilers don't insist) – sehe Nov 11 '15 at 17:42
  • Thanks, I thought I was seriously behind in still using `enum` rather than learning the correct way to use `constexpr` and I thought the standards committee had fixed that giant flaw in the language design. Sounds like it is not yet time to unlearn all the ugly work arounds for that language flaw. – JSF Nov 11 '15 at 17:47
  • @JSF the most convincing arguments to me are (a) it's not broken (b) it is clear idiom (c) MSVC doesn't even know constexpr in popular versions. In a c++14 codebase I'll write `constexpr` all the way :) – sehe Nov 11 '15 at 19:37
0

It's definitely worth mentioning that, within a class, an enum value declaration will not consume storage, whereas the various flavours of const[expr] int will end up occupying 4/8/however many bytes.

Thus, if someone needs a struct to contain only other members that occupy a defined number of bytes (e.g. a POD that gets mapped onto a byte structure from another system), specifying constants as enums seems to be the only way to do this.

Perhaps rare, but a very valid reason for this way of doing it.

underscore_d
  • 6,309
  • 3
  • 38
  • 64