Topic: volatile defective standard - Defect Report
Author: Roshan Naik <someone@nowhere.com>
Date: Mon, 20 Dec 2004 01:12:33 CST Raw View
Andrew Koenig wrote:
> "Roshan Naik" <someone@nowhere.com> wrote in message
> news:SuAWc.32062$9Y6.6618@newsread1.news.pas.earthlink.net...
>
>
>>In the above code you will see that the compiler does not auto-generate
>>a volatile version of operator=, nor is the compiler creating a default
>>copy c-tor that takes a reference to volatile A.
>>
>>For the "powers that be" would this posting suffice to qualify as a
>>defect report or would you prefer me to make a more formal write up
>>which includes exact modifications required to the standard's text ?
>
>
> The behavior you described is not a defect: The committee discussed the
> issue and consciously decided that they wanted it that way.
>
Any idea as to why ?
I looked at the core language "defect reports" and "closed issues"
lists. Could not find anything there.
-Roshan
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: algrant@myrealbox.com (Al Grant)
Date: Mon, 20 Dec 2004 01:12:18 CST Raw View
AlbertoBarbati@libero.it (Alberto Barbati) wrote in message news:<6hQWc.55211$1V3.1419071@twister2.libero.it>...
> I believe that's intentional. Volatile objects (especially non-trivial
> ones) cannot be safely copied without a complete understanding of all
> side-effects, something that the compiler cannot reasonably know.
That's also true for e.g. a 64-bit integer or double-precision type
on a machine with a 32-bit datapath. There are real problems with
'large' types independently of whether the types are structures.
If the motivation was safety (rather than "making the synthesised
functions work with volatile would be messy, so let's find a reason
not to do it") then implementations should be permitted to define
a maximum size over which (built in) volatile assignment was not
allowed. C++ has already broken compatibility with C over volatile
struct assignment so this would not be a big deal.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: "Andrew Koenig" <ark@acm.org>
Date: Mon, 20 Dec 2004 21:10:32 CST Raw View
"Roshan Naik" <someone@nowhere.com> wrote in message news:zwYWc.12772
>> The behavior you described is not a defect: The committee discussed the
>> issue and consciously decided that they wanted it that way.
> Any idea as to why ?
> I looked at the core language "defect reports" and "closed issues" lists.
> Could not find anything there.
That's because the discussion was well before the original standard was
published.
If I remember correctly, the main reason was that the committee didn't want
"volatile" to propagate throughout the language the way "const" did.
Here's an example:
class X {
// ...
};
struct Y {
X a, b;
};
Suppose the author of Y has not defined an assignment operator, and also
suppose that volatile assignment is made possible by default. Then the
compiler will effectively generate the following:
struct Y {
X a, b;
Y& operator=(const volatile Y& y) {
a = y.a;
b = y.b;
return *this;
}
};
(and similarly for the copy constructor).
Consider the effect of this automatically generated assignment operator on
the author of class X. Suppose X looks like this:
class X {
// ...
X& operator=(const X&);
// ...
};
Then this program would not compile, because it would be trying to bind a
const X& (the parameter to X::operator=) to a const volatile object (the
parameter "y" in Y's assignment operator).
So it would be necessary in practice to do one of two things:
1) Insist that every class author rewrite every copy constructor and
assignment operator to accept const volatile T& parameters, or
2) Allow a nonvolatile reference to bind to a volatile object.
(1) would impose an unacceptable burden on existing programs and
programmers. (2) would make it impossible to maintain any kind of assurance
that the compiler would not perform optimizations that volatile prohibits.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: Roshan Naik <someone@nowhere.com>
Date: Sat, 4 Sep 2004 07:33:45 GMT Raw View
> I'm not trying to achieve anything. In fact, I never used volatile in
> many years of C++ programming ;). What I believe, though, is that where
> volatile is involved there is high probability that atomicity is also an
> issue. So *because* volatile does not achieve atomicity, giving the
> programmer a false sense of security that he might get it is going to be
> bad.
>
If volatile has nothing to do with atomicity, how is there a false sense of
security being given to the programmer. And what has this to do with
the question of the default constructors not supporting it (subject of this
thread) ?
-Roshan
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: Alberto Barbati <AlbertoBarbati@libero.it>
Date: Sat, 4 Sep 2004 19:04:43 GMT Raw View
Roshan Naik wrote:
>
> If volatile has nothing to do with atomicity, how is there a false sense of
> security being given to the programmer. And what has this to do with
> the question of the default constructors not supporting it (subject of this
> thread) ?
> -Roshan
>
Consider this example, deliberately complicated to slightly obfuscate
the problem. Fortunately, it's currently illegal in C++:
struct POD { int a, b; };
volatile int int_var;
volatile POD pod_var;
template <typename T>
void dump_object(T x) { ... } // notice: pass by value
int main()
{
start_some_thread_function();
for(;;)
{
dump_object(int_var); // legal
dump_object(pod_var); // illegal!
}
}
The first call to dump_object() is legal, because the compiler can copy
a volatile int by just turning off optimizations. The second call is
illegal because the compiler can't copy the volatile POD. That's a safe
bet, because even if the compiler turned off all optimizations, the copy
wouldn't be atomic so it can't ensure that dump_object() receives a
valid copy to work with.
If the compiler provided the default copy ctor from volatile, such ctor
would be invoked _implicitly_ and the code would compile, potentially
introducing a bug that is going to be hard to detect.
Suppose the programmer that writes function main() is different from the
one writing the template dump_object() (quite likely in large projects).
The false sense of security comes from the fact that the main()
programmer may be unaware that a copy is being made and, over-confident
in the semantic of volatile, may think that the code is safe, while it's
not.
Regards,
Alberto
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: someone@nowhere.com (Roshan Naik)
Date: Wed, 1 Sep 2004 04:13:08 GMT Raw View
Alberto Barbati wrote:
> Roshan Naik wrote:
> > Alberto Barbati wrote:
> >>
> >> I believe that's intentional. Volatile objects (especially non-trivial
> >> ones) cannot be safely copied without a complete understanding of all
> >> side-effects, something that the compiler cannot reasonably know.
> >
> > Since the compiler is looking at the definition of the class what does
> > the compiler not know that it needs to know ?
> > What more does the compiler needs to know just to turn off all
> > optimizations related to read/write accesses on that object in the
> > constructor ?
> >
>
> That might work if you are going to copy one single object of a basic
> type. For example, to copy a volatile int you may simply need to turn
> off optimizations and/or use low-level instruction that are known to be
> atomic. But as soon as you have two objects, you are in deep troubles...
> Consider this:
>
> struct Foo
> {
> int a;
> int b;
> };
>
> How do you copy a volatile Foo object? Assuming it turns off all
> optimizations, the best the compiler can do *without help from
> programmer* is to perform the copy member-wise. But what if the value of
> "b" changes (because of a concurrent access) after "a" has been copied
> but before "b" is? The result would be corrupted and probably invalid
> (in the sense that it may not satisfy a semantic requirement or a class
> invariant).
When class invariants are being broken for a short period of time it should
be
done in a critical section (if MT is an issue) and restored before the
end of the critical section. It is the programmer's responsibility to
ensure correct synchronization... using appropriate techniques.
if he doesnt find the compiler generated implementaion useful,
he can always redefine. Just as in the case of non-volatile constructors,
assignment operator etc.
If you are trying to achieve atomicity semantics from volatile.... you are
using the wrong tool.
- Roshan
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: AlbertoBarbati@libero.it (Alberto Barbati)
Date: Thu, 2 Sep 2004 04:30:52 GMT Raw View
Roshan Naik wrote:
>
> When class invariants are being broken for a short period of time it should
> be
> done in a critical section (if MT is an issue) and restored before the
> end of the critical section. It is the programmer's responsibility to
> ensure correct synchronization... using appropriate techniques.
> if he doesnt find the compiler generated implementaion useful,
> he can always redefine. Just as in the case of non-volatile constructors,
> assignment operator etc.
>
That's exactly what I said. The difference is that a non-volatile
default copy ctor may break the invariant in precise circumstances the
programmer is hopefully familiar with and so it makes sense to have the
user override only it if needed. OTOH, the probability that a volatile
default copy ctor will break the invariant is much higher! So 1) it's
stupid to have the compiler provide something that's probably useless
and 2) it's even dangerous because it may lead the unaware programmer in
a programming nightmare.
> If you are trying to achieve atomicity semantics from volatile.... you are
> using the wrong tool.
I'm not trying to achieve anything. In fact, I never used volatile in
many years of C++ programming ;). What I believe, though, is that where
volatile is involved there is high probability that atomicity is also an
issue. So *because* volatile does not achieve atomicity, giving the
programmer a false sense of security that he might get it is going to be
bad.
Just my opinion,
Alberto
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: AlbertoBarbati@libero.it (Alberto Barbati)
Date: Wed, 25 Aug 2004 04:30:18 GMT Raw View
Roshan Naik wrote:
>
> The language seem to be volatile-defective in several places.
IMHO, it isn't.
> In the above code you will see that the compiler does not auto-generate
> a volatile version of operator=, nor is the compiler creating a default
> copy c-tor that takes a reference to volatile A.
I believe that's intentional. Volatile objects (especially non-trivial
ones) cannot be safely copied without a complete understanding of all
side-effects, something that the compiler cannot reasonably know. It's
best to let the programmer define the copy ctor/operator= if it's really
needed. Allowing the compiler to auto-generate a volatile copy
ctor/operator= would give the programmer a false sense of security that
will certainly lead her into big troubles.
>
> For the "powers that be" would this posting suffice to qualify as a
> defect report or would you prefer me to make a more formal write up
> which includes exact modifications required to the standard's text ?
>
See FAQ #15: http://www.jamesd.demon.co.uk/csc/faq.html#B15
Alberto
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: ark@acm.org ("Andrew Koenig")
Date: Wed, 25 Aug 2004 04:40:13 GMT Raw View
"Roshan Naik" <someone@nowhere.com> wrote in message
news:SuAWc.32062$9Y6.6618@newsread1.news.pas.earthlink.net...
> In the above code you will see that the compiler does not auto-generate
> a volatile version of operator=, nor is the compiler creating a default
> copy c-tor that takes a reference to volatile A.
>
> For the "powers that be" would this posting suffice to qualify as a
> defect report or would you prefer me to make a more formal write up
> which includes exact modifications required to the standard's text ?
The behavior you described is not a defect: The committee discussed the
issue and consciously decided that they wanted it that way.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: someone@nowhere.com (Roshan Naik)
Date: Thu, 26 Aug 2004 00:05:27 GMT Raw View
Alberto Barbati wrote:
> Roshan Naik wrote:
>
>>
>> The language seem to be volatile-defective in several places.
>
>
> IMHO, it isn't.
>
>> In the above code you will see that the compiler does not
>> auto-generate a volatile version of operator=, nor is the compiler
>> creating a default copy c-tor that takes a reference to volatile A.
>
>
> I believe that's intentional. Volatile objects (especially non-trivial
> ones) cannot be safely copied without a complete understanding of all
> side-effects, something that the compiler cannot reasonably know.
Since the compiler is looking at the definition of the class what does
the compiler not know that it needs to know ?
What more does the compiler needs to know just to turn off all
optimizations related to read/write accesses on that object in the
constructor ?
-Roshan
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: AlbertoBarbati@libero.it (Alberto Barbati)
Date: Thu, 26 Aug 2004 06:19:23 GMT Raw View
Roshan Naik wrote:
> Alberto Barbati wrote:
>>
>> I believe that's intentional. Volatile objects (especially non-trivial
>> ones) cannot be safely copied without a complete understanding of all
>> side-effects, something that the compiler cannot reasonably know.
>
> Since the compiler is looking at the definition of the class what does
> the compiler not know that it needs to know ?
> What more does the compiler needs to know just to turn off all
> optimizations related to read/write accesses on that object in the
> constructor ?
>
That might work if you are going to copy one single object of a basic
type. For example, to copy a volatile int you may simply need to turn
off optimizations and/or use low-level instruction that are known to be
atomic. But as soon as you have two objects, you are in deep troubles...
Consider this:
struct Foo
{
int a;
int b;
};
How do you copy a volatile Foo object? Assuming it turns off all
optimizations, the best the compiler can do *without help from
programmer* is to perform the copy member-wise. But what if the value of
"b" changes (because of a concurrent access) after "a" has been copied
but before "b" is? The result would be corrupted and probably invalid
(in the sense that it may not satisfy a semantic requirement or a class
invariant).
Turning off optimizations is not enough to copy a complex object, you
need to know the semantic of the object and that's something that's not
automatically detectable from the source code. That's what comments are
for ;-)
Alberto
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: someone@nowhere.com (Roshan Naik)
Date: Tue, 24 Aug 2004 20:08:13 GMT Raw View
struct A {};
int main()
{
A a1, a2;
a1=a2; // fine ... operator= found
A a3(a2); // fine... copy-ctor
volatile A v1 , v2;
v1=v2; // error !! no volatile assignment available
A v3(v2); // error !! copy-ctor does not take a volatile
return 0;
}
The language seem to be volatile-defective in several places.
The are core language issues are demonstated above.
The library doesn provide volatile versions of most (any ?) member
function. Thus you can declare library objects as volatile but cant
really use them. I think the library related stuff can be overlooked
however.
In the above code you will see that the compiler does not auto-generate
a volatile version of operator=, nor is the compiler creating a default
copy c-tor that takes a reference to volatile A.
For the "powers that be" would this posting suffice to qualify as a
defect report or would you prefer me to make a more formal write up
which includes exact modifications required to the standard's text ?
-Roshan Naik
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]