Update
turns out this is just another case of "c++ is not c blues"
What I want
const char hex[16] = "0123456789ABCDEF";
the only thing that works
char hex[16] = "01234开发者_运维问答56789ABCDE"; hex[15] = "F";
are there any compiler options or something I can do to make strings not null terminated in the gcc compiler. so that I can make a(n) constant array
No need for a compiler option, it's already non-NUL terminated. The standard says a NUL should only be added if it can fit, otherwise it would be an overflow. It may just be that the next byte in memory past your array is \0
§ 6.7.8p14
An array of character type may be initialized by a character string literal, optionally enclosed in braces. Successive characters of the character string literal (including the terminating null character if there is room or if the array is of unknown size) initialize the elements of the array.
No. NUL-terminated strings are intrinsic to the language. You can have a character array though, and set each character one by one:
char hex [] = {'0', '1', '2', ... 'F'};
You answered your own question. If you explicitly give the array a length, as in:
const char hex[16] = "0123456789ABCDEF";
then of course it won't be null-terminated because there is no storage reserved for null termination. (hex[16]
is outside the bounds of the object and thus reading or writing it is undefined behavior. If it happens to read as 0, that's UB for ya...)
It's only if you leave the length implicit, as in:
const char hex[] = "0123456789ABCDEF";
or if you use the string literal as an object rather than as an initializer, that it will have null termination.
By the way, why do you care if the null termination is there or not, if you're not planning to use it. Are you trying to shave bytes off your binary? :-)
I believe the question is a bit unclear: In C, the qoted initialization:
static const char hex[16] = "0123456789ABCDEF";
is legal. In C++, it is not. So it is one of the pieces of code, that fail (fortunately at compile time), when you move from C to C++.
It would be nice to have a way to force string literals without termination \0 byte. Something like:
static const char hex[16] = "0123456789ABCDEF\!0";
where the \!0
at the end tells the compiler to not zero-terminate the string! \!
or even \!0
anywhere else in the string would behave unmodified, so just put out a literal !
or !0
.
There actually is a partly solution for this issue in C++17: constexpr
functions may return objects of type std::array
. So, instead of initializing a const C array, we initialize a constexpr C++ std::array
instead. This template function strips the terminator:
template<typename CHAR, unsigned long N>
constexpr inline std::array<CHAR, N-1> strip_terminator(const CHAR (&in)[N])
{
std::array<CHAR, N-1> out {};
for(unsigned long i = 0; i < N-1; i++) {
out[i] = in[i];
}
return out;
}
And it can be used as follows:
constexpr std::array<char, 16> hex = strip_terminator("0123456789ABCDEF");
Everything is done at compile time, even with optimization off: The array hex
becomes a constant of the desired size and the desired content, without the unwanted zero termination byte.
Strings are null terminated in C. If you want to populate a non-null-terminated char array you can use an array initializer.
精彩评论