Title
Is a volatile-qualified type really a POD?
Status
cd3
Section
6.9 [basic.types]
Submitter
John Maddock

Created on 2004-12-30.00:00:00 last changed 41 months ago

Messages

Date: 2013-04-15.00:00:00

[Moved to DR at the April, 2013 meeting.]

Date: 2016-06-15.00:00:00

Notes from the June, 2016 meeting:

The resolution of issue 2094 revert the changes above revert the changes of volatile qualification on trivial copyability.

Date: 2012-11-03.00:00:00

Proposed resolution, October, 2012:

  1. Change 6.9 [basic.types] paragraph 9 as follows:

  2. ...Scalar types, trivially copyable class types (Clause 12 [class]), arrays of such types, and cv-qualified non-volatile const-qualified versions of these types (6.9.3 [basic.type.qualifier]) are collectively called trivially copyable types. Scalar types, trivial class types...
  3. Change 10.1.7.1 [dcl.type.cv] paragraphs 6-7 as follows:

  4. What constitutes an access to an object that has volatile-qualified type is implementation-defined. If an attempt is made to refer to an object defined with a volatile-qualified type through the use of a glvalue with a non-volatile-qualified type, the program behavior is undefined.

    [Note: volatile is a hint to the implementation to avoid aggressive optimization involving the object because the value of the object might be changed by means undetectable by an implementation. Furthermore, for some implementations, volatile might indicate that special hardware instructions are required to access the object. See 4.6 [intro.execution] for detailed semantics. In general, the semantics of volatile are intended to be the same in C++ as they are in C. —end note]

  5. Change 15.8 [class.copy] paragraph 12 as follows:

  6. A copy/move constructor for class X is trivial if it is not user-provided, its declared parameter type is the same as if it had been implicitly declared, and if

    • class X has no virtual functions (13.3 [class.virtual]) and no virtual base classes (13.1 [class.mi]), and

    • class X has no non-static data members of volatile-qualified type, and

    • ...

  7. Change 15.8 [class.copy] paragraph 25 as follows:

  8. A copy/move assignment operator for class X is trivial if it is not user-provided, its declared parameter type is the same as if it had been implicitly declared, and if

    • class X has no virtual functions (13.3 [class.virtual]) and no virtual base classes (13.1 [class.mi]), and

    • class X has no non-static data members of volatile-qualified type, and

    • ...

Date: 2005-04-15.00:00:00

Notes from the April, 2005 meeting:

It is not clear whether the volatile qualifier actually guarantees atomicity in this way. Also, the work on the memory model for multithreading being done by the Evolution Working Group seems at this point likely to specify additional semantics for volatile data, and that work would need to be considered before resolving this issue.

(See also issue 1746.)

Date: 2004-12-30.00:00:00

In 6.9 [basic.types] paragraph 10, the standard makes it quite clear that volatile qualified types are PODs:

Arithmetic types (6.9.1 [basic.fundamental]), enumeration types, pointer types, and pointer to member types (6.9.2 [basic.compound]), and cv-qualified versions of these types (6.9.3 [basic.type.qualifier]) are collectively called scalar types. Scalar types, POD-struct types, POD-union types (clause 12 [class]), arrays of such types and cv-qualified versions of these types (6.9.3 [basic.type.qualifier]) are collectively called POD types.

However in 6.9 [basic.types] paragraph 3, the standard makes it clear that PODs can be copied “as if” they were a collection of bytes by memcpy:

For any POD type T, if two pointers to T point to distinct T objects obj1 and obj2, where neither obj1 nor obj2 is a base-class subobject, if the value of obj1 is copied into obj2, using the std::memcpy library function, obj2 shall subsequently hold the same value as obj1.

The problem with this is that a volatile qualified type may need to be copied in a specific way (by copying using only atomic operations on multithreaded platforms, for example) in order to avoid the “memory tearing” that may occur with a byte-by-byte copy.

I realise that the standard says very little about volatile qualified types, and nothing at all (yet) about multithreaded platforms, but nonetheless this is a real issue, for the following reason:

The forthcoming TR1 will define a series of traits that provide information about the properties of a type, including whether a type is a POD and/or has trivial construct/copy/assign operations. Libraries can use this information to optimise their code as appropriate, for example an array of type T might be copied with a memcpy rather than an element-by-element copy if T is a POD. This was one of the main motivations behind the type traits chapter of the TR1. However it's not clear how volatile types (or POD's which have a volatile type as a member) should be handled in these cases.

History
Date User Action Args
2017-02-06 00:00:00adminsetmessages: + msg6097
2014-03-03 00:00:00adminsetstatus: drwp -> cd3
2013-10-14 00:00:00adminsetstatus: dr -> drwp
2013-05-03 00:00:00adminsetstatus: ready -> dr
2012-11-03 00:00:00adminsetstatus: review -> ready
2012-01-17 00:00:00adminsetmessages: + msg3598
2012-01-17 00:00:00adminsetstatus: ready -> review
2011-09-06 00:00:00adminsetmessages: + msg3426
2011-09-06 00:00:00adminsetstatus: open -> ready
2005-05-01 00:00:00adminsetmessages: + msg1172
2004-12-30 00:00:00admincreate