This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
Re: [patch] fix pre-/post- in-/decrement
- From: "Ulrich Weigand" <uweigand at de dot ibm dot com>
- To: dan at codesourcery dot com (Daniel Jacobowitz)
- Cc: ken at linux dot vnet dot ibm dot com (Ken Werner), gdb-patches at sourceware dot org, brobecker at adacore dot com (Joel Brobecker)
- Date: Tue, 5 Oct 2010 15:28:19 +0200 (CEST)
- Subject: Re: [patch] fix pre-/post- in-/decrement
Daniel Jacobowitz wrote:
> On Tue, Oct 05, 2010 at 01:24:51AM +0200, Ulrich Weigand wrote:
> > - If you execute "set *$p = *$q = 0" and the write to *$q fails,
> > do you really expect *$p to be set to the old value of *$q
> > instead of to 0?
>
> Yes, I would expect that. To me, this is roughly "the debugger treats
> all pointers as volatile".
The thing is, I had interpreted the C standard to read that even if
pointers p and q *are* volatile, a statement like "*p = *q = 0" would
still just trigger two writes, and no reads.
Current GCC implementation agrees with this reading:
This code:
int f (volatile int *p)
{
return *p = 0;
}
void g (volatile int *p, int *result)
{
*result = *p = 0;
}
compiles to (using gcc-head -O2 on i386):
f:
movl 4(%esp), %eax
movl $0, (%eax)
xorl %eax, %eax
ret
g:
movl 4(%esp), %eax
movl $0, (%eax)
movl 8(%esp), %eax
movl $0, (%eax)
ret
However, it seems this was not always completely clear, and until very
recently, the implementation in GCC was not quite consistent either:
E.g. using Ubuntu 4.4.3 we get:
f:
movl 4(%esp), %eax
movl $0, (%eax)
xorl %eax, %eax <<= retval is hard-coded to 0
ret
g:
movl 4(%esp), %eax
movl $0, (%eax)
movl (%eax), %edx <<= extra read from *p
movl 8(%esp), %eax
movl %edx, (%eax)
ret
This behavior was discussed at length on the GCC mailing list starting at:
http://gcc.gnu.org/ml/gcc-patches/2010-06/msg02001.html
resulting in the behavior as now described at:
http://gcc.gnu.org/onlinedocs/gcc/Volatiles.html#Volatiles
"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. [...] If you need
to read the volatile object after an assignment has occurred, you must use a
separate expression with an intervening sequence point."
The current behavior is consistent with what C++ requires, and what most
other C compilers implement as well.
To reduce the potential for confusion, it seems to me GDB ought to mirror
that behavior as well ...
Bye,
Ulrich
--
Dr. Ulrich Weigand
GNU Toolchain for Linux on System z and Cell BE
Ulrich.Weigand@de.ibm.com