如何复制/设置一个易失的std::string?

6
我该如何复制一个`volatile std::string`?由于 `volatile` 没有复制构造函数,也没有像 `c_str` 那样允许 `volatile` 访问的方法。`operator=` 似乎也不能设置 `volatile`。看起来 `std::string` 作为一个 `volatile` 对象是无法使用的。这是有意为之的吗?还是我错过了某种使用方法?
注意:我有简单的解决方法,只是在尝试在一些低级代码中使用字符串时遇到了这个问题。

2
volatile std::string非常不对。你到底想做什么? - BЈовић
3
volatile的意思是对象存在于C++内存模型之外。我认为,对于动态容器而言,这个概念几乎没有任何用处。 - Kerrek SB
我正在测试是否可以在我的编译器的JIT中替换malloc/free调用。这是中止处理的一部分(使用setjmp)。就标准而言,这是完全未定义的领域,但它让我对易失性字符串产生了好奇。 - edA-qa mort-ora-y
1个回答

3
正如您所指出的,std::string 的成员函数都没有被标记为volatile,因此您不能对volatile std::string执行任何操作。我认为唯一的选择是去掉volatile并在结果上执行操作,如下所示:
const_cast<std::string&>(myVolatileString) = "Now I'm different!"

从根本上讲,你可能不应该创建一个volatile std::string。对于可能被外部源改变或被多个线程修改的对象,使用volatile是适当的。然而,第一种情况非常罕见,需要一些非常特殊的硬件才能知道std::string的布局。第二种情况不安全,因为std::string不是线程安全的。

希望这有所帮助!


1
const_cast是否会去除对象的volatile属性?也就是说,它使得访问这个对象时好像它没有被声明为“volatile”吗? - edA-qa mort-ora-y
@edA-qamort-ora-y- 是的。它返回一个非volatile引用到对象,然后可以像任何非volatile字符串一样处理。 - templatetypedef
@BЈовић- 在C++11中,volatile表示该值可能会被另一个线程写入而无需锁定,因此编译器不应尝试优化对象的读取。 - templatetypedef
@templatetypedef 我听说过不同的说法,包括这里。是的,它的意思是“不要优化掉读取”,但据我所知,一个普通的(例如)int不会被原子地读取或写入,因此你仍然会得到UB。你确定你没有混淆C++的volatile和Java的volatile,后者确实做了一些这样的事情吗? - user395760
我对volatile的线程方面不感兴趣。我正在使用setjmp/longjmp,并希望防止跨越该边界的优化。 - edA-qa mort-ora-y
哦,天啊……这是另一个麻烦问题。volatile并不能保护你免受此类问题的影响。C++规范指出:“函数签名longjmp(jmp_buf jbuf, int val)在这个国际标准中具有更受限制的行为。如果任何自动对象将被由于抛出异常而转移控制到程序中的另一点(目标点)而被销毁,那么在传输控制到相同(目标)点的throw点处调用longjmp(jbuf, val)将具有未定义的行为。” - templatetypedef

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接