gcc 的非空终止字符串编译器选项

发布于 2024-10-05 21:23:01 字数 297 浏览 3 评论 0原文

更新

事实证明,这只是“c++ 不是 c blues”的另一种情况,


我想要

const char hex[16] = "0123456789ABCDEF";

唯一有效的方法

char hex[16] = "0123456789ABCDE"; hex[15] = "F";

是有任何编译器选项或者我可以做的事情来使 gcc 编译器中的字符串不以 null 结尾。这样我就可以制作一个(n)常量数组

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] = "0123456789ABCDE"; 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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

你的他你的她 2024-10-12 21:23:02

不需要编译器选项,它已经以非NUL 终止。标准规定,只有在可以容纳的情况下才应添加 NUL,否则就会溢出。可能只是数组后面的内存中的下一个字节是 \0

§ 6.7.8p14

字符数组
类型可以由字符初始化
字符串文字,可选
括在大括号中。字符串的连续字符
文字(包括
如果有空间
或者数组是的话则终止空字符
未知大小)初始化
数组的元素。

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.

烂人 2024-10-12 21:23:02

不会。以 NUL 结尾的字符串是该语言固有的。不过,您可以拥有一个字符数组,并一一设置每个字符:

char hex [] = {'0', '1', '2', ... 'F'};

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'};
不交电费瞎发啥光 2024-10-12 21:23:02

你回答了你自己的问题。如果您显式地给数组指定一个长度,如下所示:

const char hex[16] = "0123456789ABCDEF";

那么它当然不会以空终止,因为没有为空终止保留存储空间。 (hex[16] 超出了对象的边界,因此读取或写入它是未定义的行为。如果它碰巧读为 0,那就是 UB 对你来说......)

只有当你离开时隐含的长度,如:

const char hex[] = "0123456789ABCDEF";

或者如果您使用字符串文字作为对象而不是初始化器,则它将具有 null 终止符。

顺便说一句,如果您不打算使用它,为什么要关心空终止是否存在。您是否想从二进制文件中删除字节? :-)

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? :-)

染火枫林 2024-10-12 21:23:02

我相信这个问题有点不清楚:在C中,引用的初始化:

static const char hex[16] = "0123456789ABCDEF";

是合法的。在 C++ 中,情况并非如此。因此,当您从 C 迁移到 C++ 时,它是失败的代码之一(幸运的是在编译时)。

如果有一种方法可以强制字符串文字不终止 \0 字节,那就太好了。类似于:

static const char hex[16] = "0123456789ABCDEF\!0";

末尾的 \!0 告诉编译器不要以零终止字符串! \! 甚至 \!0 字符串中任何其他位置的行为都不会被修改,因此只需输出文字 !!0

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 .

白云不回头 2024-10-12 21:23:02

实际上,C++17 中对此问题有一个部分解决方案:constexpr 函数可能返回 std::array 类型的对象。因此,我们不是初始化 const C 数组,而是初始化 constexpr C++ std::array。这个模板函数去掉了终止符:

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;
}

它可以按如下方式使用:

constexpr std::array<char, 16> hex = strip_terminator("0123456789ABCDEF");

一切都在编译时完成,即使优化关闭:数组 hex 成为所需大小和所需内容的常量,无需不需要的零终止字节。

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.

执笔绘流年 2024-10-12 21:23:02

C 中的字符串以 null 终止。如果要填充非 null 终止的 char 数组,可以使用数组初始值设定项。

Strings are null terminated in C. If you want to populate a non-null-terminated char array you can use an array initializer.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文