0

We define a function that uses a type defined elsewhere:

auto some_func(const some_type var) -> bool  { ... }

Let's say that currently some_type is an enum. But it's defined elsewhere in the codebase, and arguably could be changed. I believe because the type of "some_type" isn't necessarily guaranteed to be an enum primitive type, the const makes sense. My code reviewer believes that it's a mistake to use const because some_type is an enum.

Does it make sense to leave the "const" in here because someday some_type may change, or does it make sense to leave it out because it is an enum and will likely always be an enum?

For those marking this question as a duplicate, the question is NOT "should I use const on enums" - the question IS "should we use const if we the definition of the type is in another part of the codebase and we can't guarantee that the type will stay an enum"

  • If it's a value, the use of `const` is debatable in utility. –  Sep 05 '18 at 21:47
  • It should make no difference whether it is an enum, another built-in type, or a user defined type. What this does is prevent you from modifying `var` in the body of the function. That's it. It follows that it only makes sense in a function definition, not a declaration. – juanchopanza Sep 05 '18 at 21:47
  • `const` can be used to signal intent, even if it's a value-type. – Dai Sep 05 '18 at 21:47
  • @juanchopanza I think the reviewer is coming from the fact that the enum is already "const" so the addition of it is unneeded. – NathanOliver Sep 05 '18 at 21:48
  • @NathanOliver I don't even know what that would mean. – juanchopanza Sep 05 '18 at 21:48
  • The question isn't whether an enum is already const. It's already clear that if it's an enum that the const has no effect.. My point is that the ownership of the typedef of that type is elsewhere and may change so that it becomes an object where const matters. – David Ljung Madison Stellar Sep 05 '18 at 21:49
  • @juanchopanza You can't modify a enum value, `enum FOO { bar }; int main() { bar = 2; }` fails to compile so a `const FOO` isn't needed as you can't modify the enumeration. – NathanOliver Sep 05 '18 at 21:51
  • " so that it becomes pass-by-ref " - that can't happen unless the signature of the function changes. –  Sep 05 '18 at 21:51
  • @NathanOliver `FOO x = FOO::a; x = FOO::b;` – juanchopanza Sep 05 '18 at 21:53
  • @NeilButterworth - thanks for helping me clarify, I've edited my above comment. – David Ljung Madison Stellar Sep 05 '18 at 21:53
  • @dai - I don't believe this is a duplicate, can you see the edits I've added to the question? – David Ljung Madison Stellar Sep 05 '18 at 21:54
  • 1
    @juanchopanza Durp. Must need more coffee. Not sure why I went down that rabbit hole. – NathanOliver Sep 05 '18 at 21:54
  • "should we use const if we the definition of the type is in another part of the codebase and we can't guarantee that the type will stay an enum" - really do not see what this has to do specifically with enum types, as opposed to (say) ints. –  Sep 05 '18 at 21:56
  • Your question just taught me something about C++. I don't think, normally, you need to worry much about what some_type may become in the future. If you are concerned, you could add some `static_assert` to check that some_type is-and-continues-to-be an enum. I think that is supported in the type traits. – Eljay Sep 05 '18 at 21:58
  • 1
    It really doesn't matter, the underlying type of `enum` is _typically_ `int` but it can be any integral type equivalent to or smaller than `int`. Your reviewer is probably saying that using `const` is a mistake because from a performance pov it doesn't matter, which is dogmatic, `const` signifies intent. Also if `some_type` becomes some massively large type and needs to be changed to pass by reference then you'd need to change the function signature in your code. It's six of one or half dozen of the other but making the argument `const` isn't a mistake, it's just unnecessary for type `int`. – George Sep 05 '18 at 22:06
  • @NeilButterworth The difference between an enum type and a plain int is that we can see the type of an int from it's typename, which is int. If it's an enum we can't tell that from the type name. – David Ljung Madison Stellar Sep 05 '18 at 22:08
  • 1
    int was an example - I don't see why it makes any difference whatever the type is - it will always be a value, unless the signature of the function is changed –  Sep 05 '18 at 22:11
  • @DavidLjungMadison Yes you can see it's type, just not its underlying type. Which is what `std::underlying_type` is for. – George Sep 05 '18 at 22:12
  • 1
    Here is info on `is_enum`: https://en.cppreference.com/w/cpp/types/is_enum – Eljay Sep 05 '18 at 22:16
  • @Eljay It's an interesting idea to check the type at compile time and break if it's not enum, so if the data type ever changed you could add the const. *Or...* you could just add the const now and never have to worry about it. Why not just do that? – David Ljung Madison Stellar Sep 06 '18 at 19:17
  • I'm not sure I understand what you are worrying about. I think you misunderstand what adding `const` does here on the function parameter. It makes it so the body of the function cannot change the pass-by-value parameter, which is a local parameter copy. (Unless the code also "cheats" by using a const_cast or C style cast.) – Eljay Sep 06 '18 at 21:09

0 Answers0