From: Daniel Krügler on
On 2 Jul., 23:14, Louis Semprini <lsempr...(a)hotmail.com> wrote:
> Hello,
>
> I have read ISO/IEC JTC1 SC22 WG21 N2668 (a revision of N2647, which
> is a revision of N2534).
>
> "Concurrency Modifications to Basic String"http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2668.htm
>
> N2668 corrects a few typos from the previous versions, but there is
> still one paragraph left which has me stumped:
>
> Can anyone explain the following claim from the paper:
>
> |Thus the only real anomaly seems to be that creating the initial
> |non-const reference invalidates previously generated const
> |references. This anomaly has unfortunate consequences.
> |Typically, when v offers "container thread safety", we can do
> |
> | #pragma omp parallel for
> | for( size_t i = 0, n = v.size(); i < n; ++i ) {
> | v[i] = 0;
> | }
> |
> |However, for a basic_string v, we must insert v[0];
> |before the pragma to render the code correct.
>
> The code in the sample does not appear to include any const
> references, only non-const references, so
> 1. in what way does the code demonstrate the anomaly?
> 2. why would inserting v[0] help anything, since it is just another
> non-const reference?

The example is correct as intended, but the mentioned existence
of at least one reference to const string is implied. If such
a reference exists, the loop-code *needs* to call v[0], which
is a reference to non-const string (as you correctly recognized).
The reason for not showing this reference is the fact, that the
caller of this loop typically is not aware of their existence.

Assume this loop is part of some function:

void do_some_thing_parallel(std::string& v) {
[..] // No references to const, but anything else
#pragma omp parallel for
for( size_t i = 0, n = v.size(); i < n; ++i ) {
v[i] = 0;
}
[..]
}

Ideally any function should work, if the implemention
is only aware of the full function body. In a non-
reference-counted implementation the code is correct.
In a reference-counted one with COW it is not, because
the expression

v[0];

must be added at the beginning of the loop to ensure
that the other references perform the required
copy.

> Is the code in error? Or is there some tricky secret const reference
> that I am missing?

There is some secret, if the string implementation uses
COW.

> Perhaps the authors meant to say "v[i] = v[0]" inside the loop?

Nope, the code is correct as written.

> Though this would be an odd example as one thread would be setting
> v[0] to itself.

Exactly.

> Or perhaps the code _does_ demonstrate a problem with the string
> design, but not a problem relating to const references? I could see
> that in this scenario, when n threads simultaneously try to do the
> first 'unsharing' operation, the library would need to have proper
> thread coordination to assure that the first thread completed the
> unsharing operation before other threads attempted to generate the non-
> const reference. But that seems like an ordinary requirement and not
> one related to this paper.

The problem is based on the string design (if COW) and this
implementation detail becomes user-visible by this example.
If the call of v[0] does not happen, proper invalidation
of other references to const string won't happen correctly.

HTH & Greetings from Bremen,

Daniel Kr�gler


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]