Is it OK to use C-style cast for built-in types?

后端 未结 9 855
情书的邮戳
情书的邮戳 2020-12-01 16:09

After reading here a lot of answers about C-style casting in C++ I still have one little question. Can I use C-style casting for built-in types like long x=(long)y;

9条回答
  •  心在旅途
    2020-12-01 16:41

    If you are casting from a numeric type, to another numeric type, then I think C-style casts are preferable to *_cast. Each of the *_cast operators has a specific reason not to use it on numeric types:

    • reinterpret_cast, when applied to numeric types, does a normal numeric conversion rather than reinterpreting the bits, i.e. writing reinterpret_cast(3.14159) does not produce the integer with the same bit representation as that floating-point constant. This is contrary to intuition.
    • const_cast is never necessary on a numeric value, and if applied to a numeric variable (as opposed to a pointer or reference to a number), suggests that the type of that variable is incorrect.
    • dynamic_cast just plain doesn't make sense on numbers because numbers never have dynamic type.
    • static_cast is normally used on class types. Therefore it looks strange to apply static_cast to a number; your readers will scratch their heads and wonder if there's something they don't know about static_cast that makes it different from the C-style cast when applied to a number. (In fact, they are identical, but I had to read the relevant C++ spec section a couple times to be sure they were identical, and I still have the "something weird must be going on here" reaction.)

    and there is an additional stylistic reason to avoid them:

    • If you need to cast among numeric types, you are likely to need to do several of them in a cluster; because of that, the concision of C-style casts is important. For instance, the program I'm writing right now has a whole bunch of this sort of thing:

      uint32_t n = ((uint32_t(buf[0]) << 24) |
                    (uint32_t(buf[1]) << 16) |
                    (uint32_t(buf[2]) <<  8) |
                    (uint32_t(buf[3])      ));
      

      Using static_cast here would obscure the arithmetic, which is the important thing. (Note: those casts are unnecessary only if sizeof(uint32_t) <= sizeof(unsigned int), which is a safe assumption nowadays but I still prefer the explicitness.) (Yes, I probably ought to factor out this operation into a be32_to_cpu inline helper, but I'd still code it the same way.)

提交回复
热议问题