diff options
author | nathan <nathan@138bc75d-0d04-0410-961f-82ee72b054a4> | 1999-09-09 12:07:46 +0000 |
---|---|---|
committer | nathan <nathan@138bc75d-0d04-0410-961f-82ee72b054a4> | 1999-09-09 12:07:46 +0000 |
commit | b1a8d4ce4e42efe59d1f80b8ef14967727333070 (patch) | |
tree | 88b5b117435e72426ca1237680e644cce728803b /gcc/extend.texi | |
parent | 05b71d23bbdd926c5a5883a0f662fb747d52e25c (diff) | |
download | gcc-b1a8d4ce4e42efe59d1f80b8ef14967727333070.tar.gz |
gcc/ChangeLog:
* extend.texi (Volatiles): New node.
gcc/cp/ChangeLog:
* cp-tree.h (convert_to_void): Prototype new function.
(require_complete_type_in_void): Remove prototype.
* cvt.c (convert_to_void): New function.
(ocp_convert): Use convert_to_void.
* decl.c (cplus_expand_expr_stmt): Likewise, for complete
expressions.
* typeck.c (require_complete_type_in_void): Remove function.
(build_compound_expr): Use convert_to_void.
(build_static_cast): Likewise.
(build_c_cast): Likewise.
* semantics.c (finish_expr_stmt): Do not decay full expressions.
* typeck.c (build_x_compound_expr): Add FIXME.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@29233 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/extend.texi')
-rw-r--r-- | gcc/extend.texi | 82 |
1 files changed, 82 insertions, 0 deletions
diff --git a/gcc/extend.texi b/gcc/extend.texi index 8a3a7e725c9..5b5f3b116c6 100644 --- a/gcc/extend.texi +++ b/gcc/extend.texi @@ -3157,6 +3157,7 @@ Predefined Macros,cpp.info,The C Preprocessor}). @menu * Naming Results:: Giving a name to C++ function return values. * Min and Max:: C++ Minimum and maximum operators. +* Volatiles:: What constitutes an access to a volatile object. * C++ Interface:: You can use a single C++ header file for both declarations and definitions. * Template Instantiation:: Methods for ensuring that exactly one copy of @@ -3323,6 +3324,87 @@ Since @code{<?} and @code{>?} are built into the compiler, they properly handle expressions with side-effects; @w{@samp{int min = i++ <? j++;}} works correctly. +@node Volatiles +@section When is a Volatile Object Accessed? +@cindex accessing volatiles +@cindex volatile read +@cindex volatile write +@cindex volatile access + +Both the C and C++ standard have the concept of volatile objects. These +are normally accessed by pointers and used for accessing hardware. The +standards encourage compilers to refrain from optimizations on +concerning accesses to volatile objects that it might perform on +non-volatile objects. The C standard leaves it implementation defined +as to what constitutes a volatile access. The C++ standard omits to +specify this, except to say that C++ should behave in a similar manner +to C with respect to volatiles, where possible. The minimum either +standard specifies is that at a sequence point all previous access to +volatile objects have stabilized and no subsequent accesses have +occurred. Thus an implementation is free to reorder and combine +volatile accesses which occur between sequence points, but cannot do so +for accesses across a sequence point. The use of volatiles does not +allow you to violate the restriction on updating objects multiple times +within a sequence point. + +In most expressions, it is intuitively obvious what is a read and what is +a write. For instance + +@example +volatile int *dst = <somevalue>; +volatile int *src = <someothervalue>; +*dst = *src; +@end example + +@noindent +will cause a read of the volatile object pointed to by @var{src} and stores the +value into the volatile object pointed to by @var{dst}. There is no +guarantee that these reads and writes are atomic, especially for objects +larger than @code{int}. + +Less obvious expressions are where something which looks like an access +is used in a void context. An example would be, + +@example +volatile int *src = <somevalue>; +*src; +@end example + +With C, such expressions are rvalues, and as rvalues cause a read of +the object, gcc interprets this as a read of the volatile being pointed +to. The C++ standard specifies that such expressions do not undergo +lvalue to rvalue conversion, and that the type of the dereferenced +object may be incomplete. The C++ standard does not specify explicitly +that it is this lvalue to rvalue conversion which is responsible for +causing an access. However, there is reason to believe that it is, +because otherwise certain simple expressions become undefined. However, +because it would surprise most programmers, g++ treats dereferencing a +pointer to volatile object of complete type in a void context as a read +of the object. When the object has incomplete type, g++ issues a +warning. + +@example +struct S; +struct T @{int m;@}; +volatile S *ptr1 = <somevalue>; +volatile T *ptr2 = <somevalue>; +*ptr1; +*ptr2; +@end example + +In this example, a warning is issued for @code{*ptr1}, and @code{*ptr2} +causes a read of the object pointed to. If you wish to force an error on +the first case, you must force a conversion to rvalue with, for instance +a static cast, @code{static_cast<S>(*ptr1)}. + +When using a reference to volatile, g++ does not treat equivalent +expressions as accesses to volatiles, but instead issues a warning that +no volatile is accessed. The rationale for this is that otherwise it +becomes difficult to determine where volatile access occur, and not +possible to ignore the return value from functions returning volatile +references. Again, if you wish to force a read, cast the reference to +an rvalue. + @node C++ Interface @section Declarations and Definitions in One Header |