1

Doesn't static_cast protect against 'invalid' values to the type it's being cast to i.e Values here?

If so, it's not a good idea to print the casted value? How to ensure the print only takes place once the value is correct/valid?

enum class Values : uint8_t 
{
    One,
    Two
};

void bar(uint8_t value)
{
    Values val = static_cast<Values >(value);
    printf ("The received value = %u\n", val);
    
    switch(val)
    {
       case One:  break;
       case Two:  break;
       default:   break;
    }
}

int main()
{
    bar(static_cast<uint8_t>(60));
}

Seemingly static_cast doesn't protect against 'invalid' values so in this snippet, how should the verification be done? Something like following or there's a better way?

enum class Values : uint8_t 
{
    One,
    Two,
    Max
};

void bar(uint8_t value)
{
    Values val = static_cast<Values>(value);

    if (val < Values::Max)
       printf ("The received value = %u\n", val);
    
    switch(val)
    {
       case One:  break;
       case Two:  break;
       default:   printf ("invalid value!"); break;
    }
}
xyf
  • 664
  • 1
  • 6
  • 16
  • 1
    Does this answer your question? [What happens if you static\_cast invalid value to enum class?](https://stackoverflow.com/questions/18195312/what-happens-if-you-static-cast-invalid-value-to-enum-class) It's a language-lawyer question, so maybe a bit technical for what you are looking for, but a quote in one of the answers might suffice: *"For an enumeration whose underlying type is fixed, the values of the enumeration are the values of the underlying type."* – JaMiT Aug 04 '22 at 05:14
  • You added a `switch` statement to your example. What would happen if it swapped positions with the `printf` statement? And maybe changed the `default` behavior from `break` to `return`? – JaMiT Aug 04 '22 at 05:18
  • yeah actually I forgot to add the switch case. swapped what with `printf`? i am just wondering of a solution around it: if a condition is added around `printf`, what about `default`? maybe there's a better way? – xyf Aug 04 '22 at 05:20
  • *"swapped what with `printf`?"* -- the antecedent of "it" in my earlier comment is the `switch` statement. Sorry if that was not clear; I suppose one might think the antecedent is "your example", but that was not my intent. – JaMiT Aug 04 '22 at 05:26
  • i actually have switch case as a part of my app logic. It's just I need to see how to fit in verification of value and `default`. I could include `printf` in each switch case but I would ideally wanna just run it once outside of switch case to avoid 'repetition' – xyf Aug 04 '22 at 05:37
  • @JaMiT why was this question closed? it's not completely the same as the 'duplicated' issue. requesting you to please reopen it – xyf Aug 04 '22 at 05:41
  • @xyf The question was closed by a different `c++` gold badge user. (If you can see their name you can ping them btw. even if there is no ping suggestion). See [here](https://meta.stackexchange.com/questions/194476/someone-flagged-my-question-as-already-answered-but-its-not) for how to act if you think that the duplicate is not appropriate. Another gold badge `c++` user or three other users with >250 reputation can reopen the question. I won't do it myself since the duplicate is in my opinion not completely wrong (although I wouldn't have closed it) and since I wrote an answer. – user17732522 Aug 04 '22 at 06:10
  • Sorry, I meant >3000 reputation in the above. – user17732522 Aug 04 '22 at 06:17
  • I don't know them. Can you please suggest how should I come up with a condition to verify the valid `value` prior to using `printf` given the `switch case`? – xyf Aug 04 '22 at 06:30
  • @xyf You could edit your question to clarify how it is different than the duplicate, although be careful to not invalidate the existing answer. Currently, you start with *"Doesn't `static_cast` protect against 'invalid' values to the type it's being cast"*, which can be (awkwardly) rephrased as *"Doesn't protection happen if you `static_cast` an invalid value to an enum class?"* From that perspective, your question is a special case of *"What happens if you `static_cast` an invalid value to an enum class?"* Maybe re-focus on how to detect an invalid value, instead of on `static_cast`? – JaMiT Aug 05 '22 at 02:35
  • @JaMiT I also asked in the comments about working around the logic with switch case statements. So it's not just about static_cast in particular. I could edit the question though – xyf Aug 05 '22 at 06:03
  • @xyf [Comments are temporary](https://stackoverflow.com/help/privileges/comment). Asking in the comments is as good as not asking in the first place. Given the answer that was posted though, you might be stuck with what you asked initially. (An edit to remove the primary question -- i.e. the first line -- would invalidate that answer, and invalidating answers is bad.) Another tactic is to acknowledge that the question is both valid and not what you intended, then ask what you intended in a new question. – JaMiT Aug 05 '22 at 07:21

1 Answers1

0

No, there are no checks and there is nothing wrong with using a static_cast like this, no matter what the value is.

You specified that Values has underlying type uint8_t, so it is perfectly fine to (static_) cast between Values and uint8_t freely. There doesn't need to be a declared enumerator with a given value for the value to be valid for the enumeration. All values of the underlying type are also valid values of the enumeration type.

If you want to assure that the value is one of the enumerators, you need to write a function checking that yourself and decide on how it should act if the value does not satisfy the condition. (Should it throw an exception?)

(The rules are different if you don't specify an underlying type in an unscoped enumeration, in which case there is no fixed underlying type to substitute for uint8_t in the above and not all values of the implementation-defined underlying type are valid for the enumeration.)

user17732522
  • 53,019
  • 2
  • 56
  • 105
  • why is perfectly fine to static_cast `uint8_t` to something that doesn't even exist in `Values` enum? – xyf Aug 04 '22 at 05:05
  • @xyf All values of the underlying type are also values of the enumeration type for enumerations with fixed underlying type. The enumerators you specify are just for convenience given some of them names. – user17732522 Aug 04 '22 at 05:06