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

时间:2010-12-03 17:29:29

标签: c++ c string gcc null-terminated

更新

原来这只是“c ++不是c布鲁斯”的另一个案例


我想要什么

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

唯一有效的方法

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

是否有任何编译器选项或我可以做的事情使gc​​c编译器中的字符串不为空终止。这样我就可以制作一个(n)常数数组

6 个答案:

答案 0 :(得分:11)

不需要编译器选项,已经非NUL终止。标准说只有在NUL适合的情况下才应添加NUL,否则它将是溢出。可能只是内存中的下一个字节超过了数组\0

  

§6.7.8p14

  一个字符数组   type可以由一个字符初始化   字符串文字,可选        用括号括起来。字符串的连续字符   文字( 包括        如果有空间 或者数组是空的,则终止空字符   未知大小)初始化        数组的元素。

答案 1 :(得分:7)

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

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

答案 2 :(得分:5)

你回答了自己的问题。如果明确给出数组长度,如:

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

然后它当然不会以空值终止,因为没有为空终止保留的存储空间。 (hex[16]超出了对象的范围,因此读取或写入它是未定义的行为。如果它恰好读为0,那就是你的UB ...)

只有当你隐藏长度时,才会这样:

const char hex[] = "0123456789ABCDEF";

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

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

答案 3 :(得分:1)

实际上在 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 变成了一个具有所需大小和所需内容的常量,没有不需要的零终止字节。

答案 4 :(得分:0)

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

答案 5 :(得分:0)

我认为这个问题有点不清楚:在C中,qoted初始化:

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

是合法的。在C ++中,它不是。因此,当你从C转向C ++时,它是失败的一部分(幸运的是在编译时)。

有一种强制字符串文字而没有终止\ 0字节的方法会很好。类似的东西:

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

最后\!0告诉编译器不要对字符串进行零终止! \!甚至\!0字符串中的任何其他位置都会保持不变,因此只需输出文字!!0