char* can also be a C-style string. std::byte has the same special treatment in the standard as char and unsigned char, with the added benefit of not being used for other purposes (i.e. ASCII character or uint8, respectively).
void foo(std::unique_ptr<int> ptr) {}
void bar(std::unique_ptr<int>&& ptr) {}
int main()
{
std::unique_ptr<int> p1{new int{1}};
std::unique_ptr<int> p2{new int{2}};
foo(std::move(p1));
assert(p1 == nullptr);
bar(std::move(p2));
assert(p2 != nullptr);
}
Neither of the above asserts will fire, but from the calling site, they look exactly the same. In my opinion, the more explicit option would be to do something like `bar(std::exchange(p2, nullptr))` struct A;
enum B; // as you pointed out, not allowed by the C++ standard
// fine to declare, define, and invoke
void fooA(struct A*);
void fooB(enum B*);
// ok to forward declare, but you can't call them
void barA(struct A);
void barB(enum B); void foo();
#pragma unreachable
class bar
{
#pragma unreachable
};
namespace foobar {
#pragma unreachable
}
But pragmas can generally be used anywhere, barring tokenization issues. The end result is that `pragma unreachable` would likely end up turning into a magic function call inside the compiler, since it really only makes sense in a spot where you can invoke a function.