开发者

Non null-terminated string compiler option for gcc

开发者 https://www.devze.com 2023-01-28 22:40 出处:网络
Update turns out this is just another case of \"c++ is not c blues\" What I want const char hex[16] = \"0123456789ABCDEF\";

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.

0

精彩评论

暂无评论...
验证码 换一张
取 消