3

I have an abstract base class

class Map {
  public:
    virtual Value get(Key const &) const;
};

a database class from an external library

class Database {
  public:
    // logically const and thread-safe
    Value get(Key const &key);
};

and I started with an implementation like

class PersistentMap : public Map {
    Database db;

  public:
    Value get(Key const &key) const
    { return const_cast<Database &>(db).get(key); }
};

As the number of const_casts grew beyond bounds, I got rid of them by adding a mutable specifier to PersistentMap::db (and a comment to remind myself of its ugliness).

  1. Was my first attempt with const_cast thread-safe?
  2. Is my new approach thread-safe, or should db also be marked volatile?
Fred Foo
  • 355,277
  • 75
  • 744
  • 836
  • 4
    `// logically const and thread-safe` Huh? What about that implies thread safety? `const_cast`, `const`, and `mutable` are things from the *type system*, that has nothing to do with thread safety. So question one doesn't make any sense. Also, `volatile` is useless for multi-threading, that's a [common misconception](http://stackoverflow.com/questions/2484980/why-is-volatile-not-considered-useful-in-multithreaded-c-or-c-programming). – GManNickG Jan 20 '11 at 20:02
  • @GMan: I figured the compiler might make optimizations based on the `const`-ness of my class that would break thread safety. – Fred Foo Jan 20 '11 at 20:04
  • @larsmans: Optimizations cannot break thread-safe code. And `const`, again, just means that the value denoted by the variable cannot be modified, you can cast it, make it `mutable`, etc. Nothing about it effects its thread-safety, the *run-time* portion of the value. – GManNickG Jan 20 '11 at 20:06
  • @GMan: ok, I'm convinced. Will you post your comments as an answer, or is this a duplicate of http://stackoverflow.com/questions/2484980/why-is-volatile-not-considered-useful-in-multithreaded-c-or-c-programming? – Fred Foo Jan 20 '11 at 20:11
  • @larsmans: I don't think your problem is solved, so no and no. :) Clearly you're doing some multi-threaded work and you want to know how it should be done, so you should elaborate your code and big picture and let people show you. – GManNickG Jan 20 '11 at 20:18
  • @GMan "Optimizations cannot break thread-safe code." I don't think this is true (or at least only vacuously so, an optimization that made the code not thread safe would mean the code wasn't thread safe in the first place). Consider something like the DCLP, which is considered not thread safe, but could be on some architectures if you could rely on the compiler to not "optimize" your code. Of course the compiler the is well within its "rights" to do so, because of the "as-if" rule (since as far as it knows there is only one thread), but I think you can appreciate my point. – Logan Capaldo Jan 20 '11 at 20:25
  • @Logan: Um, surely you see the problem here: "an optimization that made the code not thread safe would mean the code wasn't thread safe in the first place" and hence "Optimizations cannot break thread-safe code." wouldn't apply... In other words, I said "If the code is thread safe, optimizations won't break it" and you said "That's wrong, unless you meant that if optimizations broke it, it wasn't thread safe." Yes, that's the same sentence, modus tollens. – GManNickG Jan 20 '11 at 20:39
  • @GMan Right, that was phrased poorly (but I am aware of the tautology). If you're saying that by definition an optimization cannot make thread safe code not thread safe, then there's no point in bringing it up. But that ignores buggy optimizations, or optimizations in compilers that don't consider threads to exist (which until C++0x for example, they are all allowed to do). I think there is room for a class of optimization that can de-thread-safify some code, especially since if you use threads at all you're in territory not covered by the standard. – Logan Capaldo Jan 20 '11 at 20:53
  • @Logan: It's not a tautology, it's an equivalence. And no, there is no point in bringing it up...except that the comment before me didn't understand that, so I brought it up. – GManNickG Jan 20 '11 at 21:02
  • @GMan I just disagree that an optimization cannot make code thread unsafe. I would say "In a compiler that is thread-aware, a correct optimization will not make code thread unsafe". – Logan Capaldo Jan 20 '11 at 21:22
  • @Logan: I'll give you that, yes. Though any time you write thread-safe code, either the language or platform are giving you that capability, and so understand to respect that when optimizing. – GManNickG Jan 20 '11 at 22:38

1 Answers1

2

It depends entirely on whether Database::get is thread-safe or not. If it contains locks to prevent concurrent access, or is otherwise safe for concurrent access, then your code is fine with either the const_cast or the mutable. Using volatile is completely irrelevant.

Chris Dodd
  • 119,907
  • 13
  • 134
  • 226