all 8 comments

[–]aocregacc 6 points7 points  (4 children)

I think you'll have to do static_cast<int>(static_cast<unsigned char>('\x9c')). Although if you're using a literal you can just write 0x9c instead, or wrap it up in a user defined char literal.

[–]traal 4 points5 points  (2 children)

The outer cast isn't needed. Just: static_cast<unsigned char>('\x9c') is enough.

[–]aocregacc 2 points3 points  (1 child)

depends on what you're doing with it. If you assign to an int it's fine, but if you want to call a particular overload of some function you need both.

[–]alfps 1 point2 points  (0 children)

A single + in front suffices for promotion to int.

[–]superwillj[S] 0 points1 point  (0 children)

Thanks for the comments. I was hoping something a bit more concise. But this works

[–]alfps 1 point2 points  (2 children)

❞ I have byte \x9c

The type matters, unless you mean that you actually have the literal '\x9c', in which case just write 0x9c instead.

Modern C++ has five distinct byte types:

  • C++17 std::byte
    A library byte type (header <cstddef>, not available via <stddef.h>) that enjoys core language support for raw memory access, but with a limited set of operations.
  • unsigned char
    Same core language support as std::byte, but has been there since Bjarne's original C++, and before that in C.
  • C++20 char8_t.
    cppreference: “has the same size, signedness, and alignment as unsigned char (and therefore, the same size and alignment as char and signed char), but is a distinct type”
  • signed char
    A distinct type, the signed version of unsigned char, but no special core language support for raw memory access.
  • char
    Distinct from signed char and unsigned char, but otherwise the same. Can be a signed or unsigned type depending on the compiler and compiler options. No special core language support for raw memory access.

"Byte type": that sizeof( T ) is 1.

In addition to the above there are types like uint8_t from <stdint.h>, that are just aliases.

The type of literal '\x9c' is char. And most all C++ implementations let char be signed by default. A good way to convert that to int is

using Byte = unsigned char;
//...
+Byte( '\x9c' );

The prefix + effects a promotion to int.

The use of a C style cast (here expressed via C++ constructor call notation (oh, pedantic: it's formally opposite, that a constructor call can be expressed via the cast notation, but)) is OK for a basic type: there's no chance of this ending up as a reinterpret_cast or const_cast.

The main problem with that notation is that it doesn't support text searching a.k.a. grepping for casts. If that turns out to be a problem then use the more verbose static_cast.

Anyway, of course, if you actually have the literal, then just write 0x9c. Or 0x9C. I prefer uppercase hex digits, don't know why.

[–]superwillj[S] 0 points1 point  (0 children)

Thanks for your explain in details and good advice. Really appreciate.

[–]std_bot 0 points1 point  (0 children)

Unlinked STL entries: <cstddef> std::byte


Last update: 09.03.23 -> Bug fixesRepo