blob: debb155f1d40f9c4f2d1a359c7825a06e7899dcd [file] [log] [blame]
<html lang="en">
<head>
<title>Volatiles - Using the GNU Compiler Collection (GCC)</title>
<meta http-equiv="Content-Type" content="text/html">
<meta name="description" content="Using the GNU Compiler Collection (GCC)">
<meta name="generator" content="makeinfo 4.13">
<link title="Top" rel="start" href="index.html#Top">
<link rel="up" href="C-Extensions.html#C-Extensions" title="C Extensions">
<link rel="prev" href="Inline.html#Inline" title="Inline">
<link rel="next" href="Extended-Asm.html#Extended-Asm" title="Extended Asm">
<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
<!--
Copyright (C) 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997,
1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
2010 Free Software Foundation, Inc.
Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.3 or
any later version published by the Free Software Foundation; with the
Invariant Sections being ``Funding Free Software'', the Front-Cover
Texts being (a) (see below), and with the Back-Cover Texts being (b)
(see below). A copy of the license is included in the section entitled
``GNU Free Documentation License''.
(a) The FSF's Front-Cover Text is:
A GNU Manual
(b) The FSF's Back-Cover Text is:
You have freedom to copy and modify this GNU Manual, like GNU
software. Copies published by the Free Software Foundation raise
funds for GNU development.-->
<meta http-equiv="Content-Style-Type" content="text/css">
<style type="text/css"><!--
pre.display { font-family:inherit }
pre.format { font-family:inherit }
pre.smalldisplay { font-family:inherit; font-size:smaller }
pre.smallformat { font-family:inherit; font-size:smaller }
pre.smallexample { font-size:smaller }
pre.smalllisp { font-size:smaller }
span.sc { font-variant:small-caps }
span.roman { font-family:serif; font-weight:normal; }
span.sansserif { font-family:sans-serif; font-weight:normal; }
--></style>
</head>
<body>
<div class="node">
<a name="Volatiles"></a>
<p>
Next:&nbsp;<a rel="next" accesskey="n" href="Extended-Asm.html#Extended-Asm">Extended Asm</a>,
Previous:&nbsp;<a rel="previous" accesskey="p" href="Inline.html#Inline">Inline</a>,
Up:&nbsp;<a rel="up" accesskey="u" href="C-Extensions.html#C-Extensions">C Extensions</a>
<hr>
</div>
<h3 class="section">6.40 When is a Volatile Object Accessed?</h3>
<p><a name="index-accessing-volatiles-2722"></a><a name="index-volatile-read-2723"></a><a name="index-volatile-write-2724"></a><a name="index-volatile-access-2725"></a>
C has the concept of volatile objects. These are normally accessed by
pointers and used for accessing hardware or inter-thread
communication. The standard encourages compilers to refrain from
optimizations concerning accesses to volatile objects, but leaves it
implementation defined as to what constitutes a volatile access. The
minimum requirement is that at a sequence point all previous accesses
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 volatile does
not allow you to violate the restriction on updating objects multiple
times between two sequence points.
<p>Accesses to non-volatile objects are not ordered with respect to
volatile accesses. You cannot use a volatile object as a memory
barrier to order a sequence of writes to non-volatile memory. For
instance:
<pre class="smallexample"> int *ptr = <var>something</var>;
volatile int vobj;
*ptr = <var>something</var>;
vobj = 1;
</pre>
<p>Unless <var>*ptr</var> and <var>vobj</var> can be aliased, it is not guaranteed
that the write to <var>*ptr</var> will have occurred by the time the update
of <var>vobj</var> has happened. If you need this guarantee, you must use
a stronger memory barrier such as:
<pre class="smallexample"> int *ptr = <var>something</var>;
volatile int vobj;
*ptr = <var>something</var>;
asm volatile ("" : : : "memory");
vobj = 1;
</pre>
<p>A scalar volatile object is read when it is accessed in a void context:
<pre class="smallexample"> volatile int *src = <var>somevalue</var>;
*src;
</pre>
<p>Such expressions are rvalues, and GCC implements this as a
read of the volatile object being pointed to.
<p>Assignments are also expressions and have an rvalue. However when
assigning to a scalar volatile, the volatile object is not reread,
regardless of whether the assignment expression's rvalue is used or
not. If the assignment's rvalue is used, the value is that assigned
to the volatile object. For instance, there is no read of <var>vobj</var>
in all the following cases:
<pre class="smallexample"> int obj;
volatile int vobj;
vobj = <var>something</var>;
obj = vobj = <var>something</var>;
obj ? vobj = <var>onething</var> : vobj = <var>anotherthing</var>;
obj = (<var>something</var>, vobj = <var>anotherthing</var>);
</pre>
<p>If you need to read the volatile object after an assignment has
occurred, you must use a separate expression with an intervening
sequence point.
<p>As bitfields are not individually addressable, volatile bitfields may
be implicitly read when written to, or when adjacent bitfields are
accessed. Bitfield operations may be optimized such that adjacent
bitfields are only partially accessed, if they straddle a storage unit
boundary. For these reasons it is unwise to use volatile bitfields to
access hardware.
</body></html>