6

How can I copy a volatile std::string? There is no copy constructor for volatile, nor does something like c_str allow volatile access. operator= also doesn't seem to allow setting a volatile. It seems like std::string is simply unusable as a volatile object. Is this intended, or am I missing some way to use it?

NOTE: I have easy workarounds, I just came upon the issue while trying to use string in some low-level code.

templatetypedef
  • 362,284
  • 104
  • 897
  • 1,065
edA-qa mort-ora-y
  • 30,295
  • 39
  • 137
  • 267
  • 2
    volatile std::string is very wrong. What exactly are you trying to do? – BЈовић Oct 27 '13 at 20:58
  • 3
    `volatile` means that the object lives outside the C++ memory model. I'd say that that notion is almost entirely unusable for a dynamic container. – Kerrek SB Oct 27 '13 at 20:59
  • I was testing to see if I could replace a malloc/free call in my compiler's JIT. It's part of the abort handling (using setjmp). Totally undefined territory as far as the standard is concerned, it just made me curious about volatile strings. – edA-qa mort-ora-y Oct 27 '13 at 21:05

1 Answers1

3

As you noted, none of the member functions on std::string are marked volatile, so you can't perform any operations on a volatile std::string. I think the only option would be to cast away volatileness and perform operations on the result, as shown here:

const_cast<std::string&>(myVolatileString) = "Now I'm different!"

Fundamentally, though, you probably shouldn't be making a volatile std::string. volatile is appropriate for objects that might be mutated by external sources or changed by multiple threads. This first case is pretty unusual and would require some very special hardware that knew the layout of std::string. The second is unsafe because std::string isn't thread-safe.

Hope this helps!

templatetypedef
  • 362,284
  • 104
  • 897
  • 1,065
  • 1
    Does the const_cast however remove the volatile nature of the object? That is, does it make the access as though it wasn't declared "volatile"? – edA-qa mort-ora-y Oct 27 '13 at 21:02
  • @edA-qamort-ora-y- Yes. It returns a non-`volatile` reference to the object, which can then be treated like any non-`volatile` string. – templatetypedef Oct 27 '13 at 21:02
  • @BЈовић- `volatile`, in C++11, indicates to the compiler that the value may be written to by another thread without locking, so the compiler should not try to optimize away reads of the object. – templatetypedef Oct 27 '13 at 21:03
  • @templatetypedef I've heard otherwise, including [here](http://stackoverflow.com/q/8819095/395760). Yes, it means "don't optimize away reads", but AFAIK a plain (for example) `int` won't be read or written atomically so you get UB anyway. Are you sure you're not confusing C++ `volatile` with Java `volatile`, which *does* do some of these things? –  Oct 27 '13 at 21:06
  • It's not the thread aspect of volatile I'm interested in. I'm using setjmp/longjmp and want to prevent optimization across that boundary. – edA-qa mort-ora-y Oct 27 '13 at 21:06
  • @edA-qamort-ora-y- Oh boy... that's a whole other can of worms. `volatile` doesn't protect you from that. The C++ spec says "The function signature longjmp(jmp_buf jbuf, int val) has more restricted behavior in this International Standard. If any automatic objects would be destroyed by a thrown exception transferring control to another (destination) point in the program, then a call to longjmp(jbuf, val) at the throw point that transfers control to the same (destination) point has undefined behavior." – templatetypedef Oct 27 '13 at 21:08