gcc 的非空终止字符串编译器选项
更新
事实证明,这只是“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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
不需要编译器选项,它已经以非NUL 终止。标准规定,只有在可以容纳的情况下才应添加 NUL,否则就会溢出。可能只是数组后面的内存中的下一个字节是
\0
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
不会。以 NUL 结尾的字符串是该语言固有的。不过,您可以拥有一个字符数组,并一一设置每个字符:
No. NUL-terminated strings are intrinsic to the language. You can have a character array though, and set each character one by one:
你回答了你自己的问题。如果您显式地给数组指定一个长度,如下所示:
那么它当然不会以空终止,因为没有为空终止保留存储空间。 (
hex[16]
超出了对象的边界,因此读取或写入它是未定义的行为。如果它碰巧读为 0,那就是 UB 对你来说......)只有当你离开时隐含的长度,如:
或者如果您使用字符串文字作为对象而不是初始化器,则它将具有 null 终止符。
顺便说一句,如果您不打算使用它,为什么要关心空终止是否存在。您是否想从二进制文件中删除字节? :-)
You answered your own question. If you explicitly give the array a length, as in:
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:
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? :-)
我相信这个问题有点不清楚:在C中,引用的初始化:
是合法的。在 C++ 中,情况并非如此。因此,当您从 C 迁移到 C++ 时,它是失败的代码之一(幸运的是在编译时)。
如果有一种方法可以强制字符串文字不终止 \0 字节,那就太好了。类似于:
末尾的
\!0
告诉编译器不要以零终止字符串!\!
甚至\!0
字符串中任何其他位置的行为都不会被修改,因此只需输出文字!
或!0
。I believe the question is a bit unclear: In C, the qoted initialization:
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:
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
.实际上,C++17 中对此问题有一个部分解决方案:
constexpr
函数可能返回std::array
类型的对象。因此,我们不是初始化 const C 数组,而是初始化 constexpr C++std::array
。这个模板函数去掉了终止符:它可以按如下方式使用:
一切都在编译时完成,即使优化关闭:数组
hex
成为所需大小和所需内容的常量,无需不需要的零终止字节。There actually is a partly solution for this issue in C++17:
constexpr
functions may return objects of typestd::array
. So, instead of initializing a const C array, we initialize a constexpr C++std::array
instead. This template function strips the terminator:And it can be used as follows:
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.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.