C ++对C字符串的引用是可能的吗?

时间:2017-08-05 12:34:50

标签: c++

在使用g ++ 4.8.2(32位标准输出= C ++ 98)重新编译我们的大型遗留应用程序时,从数据序列化程序的一部分弹出一个新的警告warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]

在g ++ 4.4.7上编译时没有警告的代码。

警告来自序列化“char&”的模板化函数,其中注释表示它是对以null结尾的字符串的引用。

我是C ++的新手......不是const char&对单个字符的引用吗?并且不会使用该引用作为C空终止字符串的起始地址是某种作弊?

我是否忽略此警告,或者其他方式,此构造的适当形式(如果有)是什么?

//! Implementations of write() for null-terminated strings.
void write(DvCsr::TName, const char*    v, long = NO_INDEX) {writeCStr(v);}
void write(DvCsr::TName, const u_char*  v, long = NO_INDEX) {writeCStr(v);}
void write(DvCsr::TName, const char&    v, long = NO_INDEX) {writeRefCStr(v);}
void write(DvCsr::TName, const u_char&  v, long = NO_INDEX) {writeRefCStr(v);}

//! Write null-terminated string data types to the stream.
template <class T>
void writeCStr(const T* start)
{
    // Find length of the string, not including null terminator,
    // and size (in bytes), including null terminator.
    const T* end = start;
    while (*end++)
        ;
    size_t len = end - start;

    // Add the string to the end of the buffer.
    mBuffer.reserve(mBuffer.size() + len);
    std::copy(start, start + len, std::back_inserter(mBuffer));
};

template <class T>
void writeRefCStr(const T &start)
{
    writeCStr((unsigned char *)start);
}

3 个答案:

答案 0 :(得分:1)

我看到两个基本问题。首先,您将单个字符转换为指针,您需要将其地址&start。其次,您从const&转换为非const指针,这可能会给出未定义的行为。

template <class T>
void writeRefCStr(const T& start)
{
    // use &start to obtain its address
    //
    // use reinterpret_cast so the compiler complains about the
    // lack of const (and make it a const unsigned char*)
    //
    writeCStr(reinterpret_cast<const unsigned char*>(&start));
}

所谓的&#34; c-style-cast&#34; aka (unsigned char*)删除所有编译器警告,因此首选C++强制转换为reintrpret_cast

答案 1 :(得分:0)

这是问题所在:

// Definition
void write(DvCsr::TName, const char&    v, long = NO_INDEX) {writeRefCStr(v);}

// Call
void writeRefCStr(const T &start){
    writeCStr((unsigned char *)start);
}

您正在使用start进行撰写。相反,你应该

    writeCStr((unsigned char *) &start);
                                ^

...以便您使用start地址进行撰写。

对于现有对象,

参考本质上是一个不可更改的别名。当某些内容作为参考传递时,您不会获得其地址。你得到了自己。您应该在引用中使用地址运算符&

答案 2 :(得分:0)

如果您正在处理一个字符串,则需要分配一个两个字符串缓冲区以确保它以空值终止。

void writeRefCStr(const T&amp; start){     const char tmp [2] = {start,0};     writeCStr(TMP); // tmp与const char *相同 }