Nic*_*las 37 c++ stdstring language-lawyer c++11
在C++ 11中,我们知道std::string
保证是连续的和以null结尾的(或更迂腐,终止于charT()
,在char
空字符0 的情况下).
我需要使用这个C API,通过指针填充字符串.它写入整个字符串+ null终止符.在C++ 03中,我总是被迫使用a vector<char>
,因为我无法假设它string
是连续的或以null结尾的.但是在C++ 11中(假设一个合适的basic_string
类,在某些标准库中仍然是不合适的),我可以.
或者我可以吗?当我这样做:
std::string str(length);
Run Code Online (Sandbox Code Playgroud)
该字符串将分配length+1
字节,最后一个由null终止符填充.非常好.但是当我把它传递给C API时,它会写出length+1
字符.它将覆盖null终止符.
不可否认,它将用空字符覆盖null终止符.赔率是好的,这将工作(事实上,我无法想象它怎么可能不工作).
但我不关心什么"有效".我想知道,根据规范,是否可以用空字符覆盖null终止符?
Xeo*_*Xeo 25
不幸的是,这是UB,如果我解释的措辞是正确的(无论如何,这是不允许的):
§21.4.5 [string.access] p2
返回:
*(begin() + pos)
ifpos < size()
,否则引用T
具有值的类型的对象charT()
; 参考值不得修改.
(编辑错误,它说T
没有charT
.)
.data()
并且.c_str()
基本上指向operator[]
(§21.4.7.1 [string.accessors] p1
):
返回:一个指针
p
,p + i == &operator[](i)
用于每个i
in[0,size()]
.
Mr.*_*C64 11
根据规范,覆盖终止NUL
应该是未定义的行为.因此,正确的做法是length+1
在字符串中分配字符,将字符串缓冲区传递给C API,然后resize()
返回到length
:
// "+ 1" to make room for the terminating NUL for the C API
std::string str(length + 1);
// Call the C API passing &str[0] to safely write to the string buffer
...
// Resize back to length
str.resize(length);
Run Code Online (Sandbox Code Playgroud)
(FWIW,我在MSVC10上尝试了"覆盖NUL"方法,它运行正常.)
我想n3092不再是现在了,但这就是我所拥有的.第21.4.5节允许访问单个元素.它需要pos <= size().如果pos <size()则获得实际元素,否则(即如果pos == size())则获得不可修改的引用.
我认为就编程语言而言,即使新值与旧值相同,也可以将一种可以修改值的访问视为修改.
g ++是否有可以链接到的迂腐图书馆?
归档时间: |
|
查看次数: |
3194 次 |
最近记录: |