It might work right now, but will not in the future.
There is a new feature coming to C++26 (https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2795r3.html) which addresses a problem related to this. Currently if you do something like this
void f()
{
const char password[] = "secret";
}
void g()
{
char str[7];
std::cout << str << '\n';
}
int main()
{
f();
g();
}
it will most likely print secret. Both functions will use the same stack space and reuse the same memory. The proposal for C++26 is to handle uninitialized variables explicitly to avoid this problem.
On the other hand this also means in your concrete case if some other function reuses the same stack space it will overwrite \x11\x01\x1E\xD0.
Someone should check the following with the standard, but I believe there is a difference between
char serialNumberCommand[] = "\x11\x01\x1E\xD0";
and
char *serialNumberCommand = "\x11\x01\x1E\xD0";
I would expect the first version to copy the string into the serialNumberCommand array. In the latter case you are just holding a pointer to an existing string in static storage. This pointer can then be handed safely to QByteArray::fromRawData as QByteArray will not hold the pointer handed to it, but the thing it points to. The thing it points to should be permanent. (I am not sure it the C++ standard guarantees this, but it is the general implementation of C strings.)
If you want something more fancy, there is not only constexpr but also constinit (since C++20). cppreference (https://en.cppreference.com/w/cpp/language/constinit) mentions that constinit declares a variable with static or thread storage duration. However, as the example on that page shows, you need to write static constinit inside a function. Just constinit alone will not do.