| Author |
Message |
Roman Mashak
Guest
|
Posted:
Mon Dec 06, 2004 4:50 pm Post subject:
volatile attribute |
|
|
Hello, All!
Could you please explain me the meaning of 'volatile' keyword when defining
variables? I don't quite understand this :(
With best regards, Roman Mashak. E-mail: mrv@tusur.ru |
|
| Back to top |
|
 |
Guy Macon
Guest
|
|
| Back to top |
|
 |
Al Borowski
Guest
|
Posted:
Mon Dec 06, 2004 5:31 pm Post subject:
Re: volatile attribute |
|
|
Roman Mashak wrote:
| Quote: | Hello, All!
Could you please explain me the meaning of 'volatile' keyword when defining
variables? I don't quite understand this :(
|
Hi,
Please read this: http://www.embedded.com/story/OEG20010615S0107
Al |
|
| Back to top |
|
 |
moocowmoo
Guest
|
Posted:
Mon Dec 06, 2004 5:32 pm Post subject:
Re: volatile attribute |
|
|
"Roman Mashak" <mrv@tusur.ru> wrote in message
news:cp1h39$4qh$1@mpeks.tomsk.su...
| Quote: | Hello, All!
Could you please explain me the meaning of 'volatile' keyword when
defining
variables? I don't quite understand this :(
With best regards, Roman Mashak. E-mail: mrv@tusur.ru
Use volatile when you don't want the compiler to make assumptions about a |
variable. The compiler will always fetch the variable rather than keeping a
copy in a register. It's used for monitoring I/O ports or variables that
might be changed by other processes.
Peter
---
Outgoing mail is certified Virus Free.
Checked by AVG anti-virus system (http://www.grisoft.com).
Version: 6.0.779 / Virus Database: 526 - Release Date: 19/10/04 |
|
| Back to top |
|
 |
Richard
Guest
|
Posted:
Mon Dec 06, 2004 6:50 pm Post subject:
Re: volatile attribute |
|
|
"Roman Mashak" <mrv@tusur.ru> wrote in message
news:cp1h39$4qh$1@mpeks.tomsk.su...
| Quote: | Hello, All!
Could you please explain me the meaning of 'volatile' keyword when
defining
variables? I don't quite understand this :(
With best regards, Roman Mashak. E-mail: mrv@tusur.ru
|
It tells the compiler that the variable can change outside of the
predictable program flow - it cannot therefore make any assumptions as to
its value when optimising. The variable must be loaded from memory each
time it is used.
Examples: A variable mapped to a register (where hardware can change the
register value), a variable that can get altered from an interrupt service
routine, a variable that can get altered by more than one task in a
multitasking system.
Regards,
Richard.
http://www.FreeRTOS.org |
|
| Back to top |
|
 |
Dave Hansen
Guest
|
Posted:
Mon Dec 06, 2004 8:49 pm Post subject:
Re: volatile attribute |
|
|
On Mon, 6 Dec 2004 20:50:58 +0900, "Roman Mashak" <mrv@tusur.ru>
wrote:
| Quote: | Hello, All!
Could you please explain me the meaning of 'volatile' keyword when defining
variables? I don't quite understand this :(
|
In simplest terms, it tells the compiler that you know something about
the variable that it doesn't, so it should do exactly what you tell it
to do with it, no more, and no less. More specifically, it tells the
compiler that access to the variable may have side effects it's not
aware of, and that the value could change by means not visible to the
compiler.
Example: at a PPOE I worked with the Zilog 8530 UART, which has two
addressable registers, the (transmit or receive) data register and the
control register. Internally it has (IIRC) 16 writable and something
like 8 readable registers. You access the internal registers by
writing their address to the control register, then reading or writing
the control register a second time.
For example, to write 0 to register 1 and then read register 2, you
would do something like
CR = 1;
CR = 0;
CR = 2;
x = CR;
If CR is not declared volatile, the compiler's optimizer is free to
reduce this sequence to the equivalent of
CR = 2;
x = 2;
Which is unlikely to be what you want. The compiler sees the
consecutive writes to CR as redundant and unnecessary, and since it
just wrote a 2 into CR, that must what is stored there, so there's no
need to read it.
The volatile keyword forces the compiler to generate code that
performs all 4 accesses to the control register.
HTH,
-=Dave
--
Change is inevitable, progress is not. |
|
| Back to top |
|
 |
Kai Ruottu
Guest
|
Posted:
Tue Dec 07, 2004 4:58 pm Post subject:
Re: volatile attribute |
|
|
On Mon, 6 Dec 2004 12:32:16 -0000, "moocowmoo" <meltyb@hotmail.com>
wrote:
| Quote: | Use volatile when you don't want the compiler to make assumptions about a
variable. The compiler will always fetch the variable rather than keeping a
copy in a register. It's used for monitoring I/O ports or variables that
might be changed by other processes.
|
Is this "fetch the variable" somehow obligatory? Quite many
architectures have opcodes for directly modifying a memory
place, for instance clearing/setting a bit in a memory place
which really is a I/O-port....
What the GNU C compiler does in the 'volatile' case :
1. load the data from the memory place into a CPU register
2. modify it
3. write it back
instead of doing the same thing as with a non-volatile variable:
a. modify the data directly in the memory place
looks being simply wrong. If an interrupt happens between the
steps 1 and 3 and the ISR for it changes the same memory
address, for instance changing some other bit there, the write
back will replace that bit to its original value... Whether this
kind of thing ever would be needed, is of course purely
theoretical....
If knowing this "feature" in GCC, one can always try to disable
interrupts during the steps 1-3, but using the opcode 'a' could
be assumed to be 'atomic' and not being possible to interrupt
when executed... That handling volatiles isn't atomic may be
a surprise for newbies, and a nuisance for those wanting as
small code as possible, three opcodes generally takes more
code memory than that one opcode. |
|
| Back to top |
|
 |
Hans-Bernhard Broeker
Guest
|
Posted:
Tue Dec 07, 2004 5:32 pm Post subject:
Re: volatile attribute |
|
|
Kai Ruottu <karuottu_miaauu_mbnet_point_fi@spam.tome.no> wrote:
| Quote: | What the GNU C compiler does in the 'volatile' case :
1. load the data from the memory place into a CPU register
2. modify it
3. write it back
instead of doing the same thing as with a non-volatile variable:
a. modify the data directly in the memory place
|
Does it? On what architecture, in what version of GCC? I'd like to
see an actual example of this behaviour.
| Quote: | looks being simply wrong.
|
Not necessarily. You're mixing up two things here: volatility and
atomicity.
It may go contrary to common wisdom, but since C has no concept of
multithreading in its language definition, flagging an object as
volatile does *not* guarantee thread-safety through atomic accesses.
That's not its intended usage, nor is the above difference actually
the one 'volatile' is supposed to cause. What volatile is supposed to
do, in this particular context, is forbid the compiler from *keeping*
the value in a register across any sequence point. I.e. for normal
objects, in the above nomenclature, a sequence of
1. 2. 2. 2. 2. 2. 3. 2. 2. 2. 3.
would be allowed, but for volatiles, that's expressly forbidden.
In fact, the only way C even tries to handle atomicity and
thread-safety is with <signal.h> and the type sigatomic_t defined in
there.
--
Hans-Bernhard Broeker (broeker@physik.rwth-aachen.de)
Even if all the snow were burnt, ashes would remain. |
|
| Back to top |
|
 |
Guy Macon
Guest
|
|
| Back to top |
|
 |
Paul Burke
Guest
|
Posted:
Tue Dec 07, 2004 6:41 pm Post subject:
Re: volatile attribute |
|
|
Kai Ruottu wrote:
| Quote: | What the GNU C compiler does in the 'volatile' case :
1. load the data from the memory place into a CPU register
2. modify it
3. write it back
instead of doing the same thing as with a non-volatile variable:
a. modify the data directly in the memory place
looks being simply wrong.
|
No, all 'volatile' means is that the compiler should read it afresh each
time it uses it, instead of reading it once and holding it in a register
if it's accessed several times.
No language standard could call for atomicity in specific places such as
IO, simply because you can't guarantee that the feature exists in the
target architecture. And even if you could, the behaviour can be wildly
different- for some ports the read reflects the actual value on the IO
pin, for others the value of the output register, for yet more the port
might have no read facility at all and return rubbish.
Paul Burke |
|
| Back to top |
|
 |
Kai Ruottu
Guest
|
Posted:
Wed Dec 08, 2004 5:48 pm Post subject:
Re: volatile attribute |
|
|
On 7 Dec 2004 12:32:27 GMT, Hans-Bernhard Broeker
<broeker@physik.rwth-aachen.de> wrote:
| Quote: | Kai Ruottu <karuottu_miaauu_mbnet_point_fi@spam.tome.no> wrote:
What the GNU C compiler does in the 'volatile' case :
1. load the data from the memory place into a CPU register
2. modify it
3. write it back
instead of doing the same thing as with a non-volatile variable:
a. modify the data directly in the memory place
Does it? On what architecture, in what version of GCC?
|
H8/300, H8/500, m68k, v850,... all these have opcodes to "directly
set/clear a bit in a memory place whose address is given in the opcode
or in a CPU register". And GCC really handles these operations with
these expected opcodes when handling non-volatile objects... How
these opcodes work internally, maybe copying the data into some
invisible register, then modifying it and writing back, isn't
important, only that none of the visible CPU registers are used.
All GCCs since 1995 or so behave this way... Maybe also earlier ones
but in 1995 RMS & Co. seem to have last done something with the
'volatile_ok' variable in the GCC code... Quite many have reported,
at least unofficially, this bug but some kind of MS-like attitude, "it
is not a bug, it is a feature" has been the normal reaction. Or
people start to talk about the C/C++ standards and that 'volatile'
should somehow trigger the memory handling from direct to
load-store...
| Quote: | I'd like to see an actual example of this behaviour.
|
Anyone can get an example with a code doing bit set/clear in a
memory place... But here is one from the H8/300 world showing
how the produced code should be :
------------------- clip -----------------------------
#define SFR __attribute__((eightbit_data))
extern volatile unsigned char SFR SCI_SSR0;
extern volatile unsigned char SFR SCI_TDR0;
/*
#define SCI_TDR0 (*(volatile unsigned char *) (0xffffdb))
#define SCI_SSR0 (*(volatile unsigned char *) (0xffffdc))
*/
/* Single char out to the serial port */
void put_ser(unsigned char c)
{
while ((SCI_SSR0 & 0x80) != 0x80)
;
SCI_TDR0 = c;
SCI_SSR0 &= 0x7F;
}
------------------- clip -----------------------------
; GCC For the Hitachi H8/300[HS]
; By Hitachi America Ltd and Cygnus Support
; Modified by Kai Ruottu
; release F-1.0.1
; -O2
.file "put_ser.c"
.section .text
.align 1
.global _put_ser
_put_ser:
..L5:
mov.b @_SCI_SSR0:8,r2l
and #128,r2l
beq .L5
mov.b r0l,@_SCI_TDR0:8
bclr #7,@_SCI_SSR0:8
rts
.end
------------------- clip -----------------------------
and here are some clips from a diff between the outputs of a
non-modified GCC and a by-me modified gcc-3.3.5 for m68k/cpu32 :
------------------- clip -----------------------------
*** quicc_335-1.s 2004-10-27 18:46:34.000000000 +0300
--- quicc_335-2.s 2004-10-27 14:33:46.000000000 +0300
***************
*** 6,13 ****
init_channel0:
move.l quicc,%a1
lea (3072,%a1),%a0
! lea (5632,%a1),%a1
! clr.l (%a1)
clr.w (%a0)
move.w #400,2(%a0)
move.b #24,4(%a0)
--- 6,12 ----
init_channel0:
move.l quicc,%a1
lea (3072,%a1),%a0
! clr.l 5632(%a1)
clr.w (%a0)
move.w #400,2(%a0)
move.b #24,4(%a0)
***************
*** 132,141 ****
move.w #2570,8(%a0)
move.l #384,4(%a0)
move.l #277348364,(%a0)
! move.l (%a0),%d0
! moveq.l #48,%d1
! or.l %d1,%d0
! move.l %d0,(%a0)
rts
.size ethernet_up, .-ethernet_up
.align 2
--- 130,137 ----
move.w #2570,8(%a0)
move.l #384,4(%a0)
move.l #277348364,(%a0)
! moveq.l #48,%d0
! or.l %d0,(%a0)
rts
.size ethernet_up, .-ethernet_up
.align 2
***************
*** 265,276 ****
extb.l %d0
moveq.l #32,%d1
and.l %d1,%d0
! add.l quicc,%d0
! move.l %d0,%a0
! lea (5632,%a0),%a0
! move.w 20(%a0),%d0
! or.w #8,%d0
! move.w %d0,20(%a0)
rts
.size quicc_finish, .-quicc_finish
.align 2
--- 261,269 ----
extb.l %d0
moveq.l #32,%d1
and.l %d1,%d0
! move.l quicc,%a0
! add.l %d0,%a0
! or.w #8,5652(%a0)
rts
.size quicc_finish, .-quicc_finish
.align 2
***************
*** 529,548 ****
lea RQB+6,%a0
move.w %a6,%d0
move.b %d0,(%a0,%a1.l)
! move.w (%a2),%d0
! and.w #8192,%d0
! move.w %d0,(%a2)
tst.b %d7
jbne .L42
! move.w (%a2),%d0
! or.w #-32768,%d0
! move.w %d0,(%a2)
jbra .L43
.align 2
.L42:
move.l %a2,%a4
clr.b %d7
.L43:
move.w (%a2),%d0
and.l #8192,%d0
addq.l #1,%d5
--- 525,541 ----
lea RQB+6,%a0
move.w %a6,%d0
move.b %d0,(%a0,%a1.l)
! and.w #8192,(%a2)
tst.b %d7
jbne .L42
! or.w #-32768,(%a2)
jbra .L43
.align 2
.L42:
move.l %a2,%a4
clr.b %d7
.L43:
+ clr.l %d0
move.w (%a2),%d0
and.l #8192,%d0
addq.l #1,%d5
***************
*** 739,748 ****
addq.l #6,%a3
addq.l #8,%a2
jbpl .L67
! subq.l #8,%a2
! move.w (%a2),%d0
! or.w #8192,%d0
! move.w %d0,(%a2)
movm.l (%sp)+,#0xc0c
rts
.size create_tx_pool, .-create_tx_pool
--- 726,732 ----
addq.l #6,%a3
addq.l #8,%a2
jbpl .L67
! or.w #8192,-8(%a2)
movm.l (%sp)+,#0xc0c
rts
.size create_tx_pool, .-create_tx_pool
------------------- clip -----------------------------
In the H8/300 case compiling the:
SCI_SSR0 &= 0x7F;
to be:
bclr #7,@_SCI_SSR0:8 ('Clear bit #7 in address SCI_SSR0')
is expected but replacing it with 'mov.b' / 'and' / 'mov.b' opcodes
would be very unexpected.... As the example shows, the C code
translated to machine code is a quite direct 1:1 translation...
As the m68k clips show, replacing a "clear the data in the given
memory address" is converted to "put the memory address into a
register and use this register as a pointer when clearing the data",
is another bug type besides that load-store seen also in the last
clip....
My local H8/300, H8/500, m68k etc. tools use a hack which seems to fix
this bug but at least one bug caused by the fix, as the example shows
.L43:
+ clr.l %d0
move.w (%a2),%d0
appears then... Clearing the target register before moving something
from memory into it, is vain and without the hack this doesn't happen.
Using a hack without fully knowing what it could cause somewhere else,
has however been the only way this far... Of course I have tried to
understand how GCC works but it could be much simpler to get someone
of the GCC-gurus to try to fix this.
Quite many 'current' CPU archs are now RISC-like, even those 8/16
bit ones (like AVR) and don't know this kind of opcodes, then there
aren't any differences between non-volatiles and volatiles with
them...
| Quote: | looks being simply wrong.
Not necessarily. You're mixing up two things here: volatility and
atomicity.
|
Maybe, I'm far from being a specialist in the C or C++ language or
its standards... My 'atomicity' simply meaned something which cannot
be interrupted when started... In the good old Z80 architecture
there were those LDIR and LDDR 'block move' opcodes, seemingly
'atomic' but these could be interrupted during their execution, but I
would be quite sure that the 'bclr', 'bset' etc. in the H8/300
architecture cannot be interrupted...
| Quote: | It may go contrary to common wisdom, but since C has no concept of
multithreading in its language definition, flagging an object as
volatile does *not* guarantee thread-safety through atomic accesses.
That's not its intended usage, nor is the above difference actually
the one 'volatile' is supposed to cause.
|
Not changing the way GCC handles I/O ports in memory places
in the non-volatile and volatile cases is what ordinary people would
expect, not that the handling will switch to those RISC-like
load-store operations because the object is volatile....
| Quote: | What volatile is supposed to
do, in this particular context, is forbid the compiler from *keeping*
the value in a register across any sequence point. I.e. for normal
objects, in the above nomenclature, a sequence of
1. 2. 2. 2. 2. 2. 3. 2. 2. 2. 3.
would be allowed, but for volatiles, that's expressly forbidden.
|
Yes, I will understand this, but cannot understand why toggling a
bit in a memory place in the H8/300 example case cannot happen as :
bset #7,@_SCI_SSR0:8 ('Set bit#7 in SCI_SSR0')
bclr #7,@_SCI_SSR0:8 ('Clear bit#7 in SCI_SSR0')
but it would maybe require 6 opcodes to do the same thing.... If this
would be allowed, someone of the GCC gurus could fix this current
feature. So there must be something which disables handling memory
places just like the CPU registers, directly, or via a pointer without
first moving the data into a CPU register and then back again after
modifying it.
I became aware of this feature more than 5 years ago and have
nagged since that, always when there is some kind of chance...
Haven't yet met an embedded person who hasn't thought this
"feature" in GCC being a bug... The GCC developers must have
some better knowledge.
People usually nag about GCC producing much bigger code than
those old commercial C compilers and in the m68k case this
"volatile bug" feature is one reason for that. The old commercial
C compilers didn't switch from direct handling to load-store with
volatile objects...
If enough embedded people will nag about this, maybe some day
we will see it being fixed... Before all the people will stop using
the H8/300, m68k, v850 etc. old (partially) CISC-type architectures,
and the fixing then being too late... With RISC-type CPUs the
"load-store" is the only and the standard way to do these things... |
|
| Back to top |
|
 |
Hans-Bernhard Broeker
Guest
|
Posted:
Wed Dec 08, 2004 7:13 pm Post subject:
Re: volatile attribute |
|
|
Kai Ruottu <karuottu_miaauu_mbnet_point_fi@spam.tome.no> wrote:
| Quote: | On 7 Dec 2004 12:32:27 GMT, Hans-Bernhard Broeker
broeker@physik.rwth-aachen.de> wrote:
Kai Ruottu <karuottu_miaauu_mbnet_point_fi@spam.tome.no> wrote:
What the GNU C compiler does in the 'volatile' case :
1. load the data from the memory place into a CPU register
2. modify it
3. write it back
instead of doing the same thing as with a non-volatile variable:
a. modify the data directly in the memory place
Does it? On what architecture, in what version of GCC?
H8/300, H8/500, m68k, v850,... all these have opcodes to "directly
set/clear a bit in a memory place whose address is given in the opcode
or in a CPU register". And GCC really handles these operations with
these expected opcodes when handling non-volatile objects... How
these opcodes work internally, maybe copying the data into some
invisible register, then modifying it and writing back, isn't
important, only that none of the visible CPU registers are used.
|
Let's get one thing straight, though: the above effect of 'volatile'
is silly, and I'm quite sure it's also unnecessary. But
1) This is not a bug of GCC. Suboptimal code is being generated for
no truly good reason, but both versions are equally correct. In other
words, it's a quality-of-implementation issue.
2) This has nothing to do with atomicity or thread-safety. Even if
*all* objects referred to by an expression statement were volatiles or
constants, it's still not guaranteed by C standards or anything else
that an interrupt somewhere during the execution of such an expression
won't lead to unexpected results. Volatile does nothing towards
protecting your values from modification between sequence points.
| Quote: | All GCCs since 1995 or so behave this way... Maybe also earlier ones
but in 1995 RMS & Co. seem to have last done something with the
'volatile_ok' variable in the GCC code... Quite many have reported,
at least unofficially, this bug but some kind of MS-like attitude, "it
is not a bug, it is a feature" has been the normal reaction. Or
people start to talk about the C/C++ standards and that 'volatile'
should somehow trigger the memory handling from direct to
load-store...
|
Not having the actual reports and replies to them makes it essentially
impossible to judge which side was right, in that discussion. The GCC
advocates you quote are right in at least one point, though: this is
not a bug, because, as I pointed out, both versions of that code are
exactly equally correct. It really is a (bad) feature.
| Quote: | #define SFR __attribute__((eightbit_data))
extern volatile unsigned char SFR SCI_SSR0;
extern volatile unsigned char SFR SCI_TDR0;
|
The example might be more convincing if you could keep it to the realm
of standard C. I.e. no __attribute__s. Arguing about the effect of
standard C modifiers on manifestly non-standard objects is futile.
[...]
| Quote: | In the H8/300 case compiling the:
SCI_SSR0 &= 0x7F;
to be:
bclr #7,@_SCI_SSR0:8 ('Clear bit #7 in address SCI_SSR0')
is expected but replacing it with 'mov.b' / 'and' / 'mov.b' opcodes
would be very unexpected....
|
Unexpected and suboptimal: yes. But not strictly incorrect.
| Quote: | Using a hack without fully knowing what it could cause somewhere else,
has however been the only way this far... Of course I have tried to
understand how GCC works but it could be much simpler to get someone
of the GCC-gurus to try to fix this.
|
Have you considered that they may have to refuse doing such a
modification because they cannot find a way to do it without
introducing secondary errors like the ones you observed with your
hacked version?
[...]
| Quote: | Maybe, I'm far from being a specialist in the C or C++ language or
its standards... My 'atomicity' simply meaned something which cannot
be interrupted when started...
|
Yes. And volatility is something else.
It would be nice if runtime systems or processors knew about what C
calls "sequence points" --- i.e. if there were any level above the
single machine instructions at which interruption could be
automatically forbidden. In such a dream system, the C compiler could
ensure a consistent state of all variables in memory at each sequence
point (for volatiles, it already does that), and the processor would
take care of the intervals between them. But since that isn't the
case, atomicity and C language programming can't, generally, be had at
the same time.
| Quote: | would be quite sure that the 'bclr', 'bset' etc. in the H8/300
architecture cannot be interrupted...
|
And even if they could, they'ld at least be no worse at that than the
long version of the read-modify-write triple-jump.
| Quote: | People usually nag about GCC producing much bigger code than
those old commercial C compilers and in the m68k case this
"volatile bug" feature is one reason for that.
|
Is the typical piece of 68k code really so wrought with volatile
objects that this problem alone would make the code "much bigger", in
total? I somehow find that hard to believe.
--
Hans-Bernhard Broeker (broeker@physik.rwth-aachen.de)
Even if all the snow were burnt, ashes would remain. |
|
| Back to top |
|
 |
Guy Macon
Guest
|
Posted:
Wed Dec 08, 2004 11:31 pm Post subject:
Re: volatile attribute |
|
|
Kai Ruottu wrote:
| Quote: |
Hans-Bernhard Broeker wrote:
Does it? On what architecture, in what version of GCC?
H8/300, H8/500, m68k, v850,... all these have opcodes to "directly
set/clear a bit in a memory place whose address is given in the opcode
or in a CPU register".
All GCCs since 1995 or so behave this way.
|
I don't have the data sheet in front of me and it's not a part I use,
but if I remember correctly the AVR Microcontroller can't do that, and
GCC supports it.
| Quote: | Not changing the way GCC handles I/O ports in memory places
in the non-volatile and volatile cases is what ordinary people would
expect,
Haven't yet met an embedded person who hasn't thought this
"feature" in GCC being a bug.
|
Well now you have. There is some question as to whether I fit
the class "ordinary people", but I am an "embedded person", and
I expect my compiler to hehave as specified in the language
definition, as opposed to hehaving the way ordinary people would
expect or behaving the way that an embedded person doesn't like.
Very few aspects of C or C++ are "what ordinary people would
expect." You can get used to almost anything.
Take a look at these webpages:
http://www.comp-inspirations.com/docs/casec.pdf
http://www0.us.ioccc.org/years.html
http://murray.newcastle.edu.au/users/ftp/pub/reports/CaseAgainstC.txt
http://www.tcm.phy.cam.ac.uk/~mjr/C/
http://lists.tunes.org/archives/moose/1993-April/000315.html
http://www.modulaware.com/mdlt35.htm |
|
| Back to top |
|
 |
David
Guest
|
Posted:
Thu Dec 09, 2004 1:57 pm Post subject:
Re: volatile attribute |
|
|
On Wed, 08 Dec 2004 18:31:10 +0000, Guy Macon wrote:
| Quote: |
Kai Ruottu wrote:
Hans-Bernhard Broeker wrote:
Does it? On what architecture, in what version of GCC?
H8/300, H8/500, m68k, v850,... all these have opcodes to "directly
set/clear a bit in a memory place whose address is given in the opcode
or in a CPU register".
All GCCs since 1995 or so behave this way.
I don't have the data sheet in front of me and it's not a part I use,
but if I remember correctly the AVR Microcontroller can't do that, and
GCC supports it.
Not changing the way GCC handles I/O ports in memory places
in the non-volatile and volatile cases is what ordinary people would
expect,
Haven't yet met an embedded person who hasn't thought this
"feature" in GCC being a bug.
Well now you have. There is some question as to whether I fit
|
It's not a bug - you are assuming "volatile" means "atomic". C does not
have any way to express "atomic", and even if it did, many processors have
no way to implement it. The generated code might be sub-optimal in space
or speed, but the generated code is correct.
| Quote: | the class "ordinary people", but I am an "embedded person", and
I expect my compiler to hehave as specified in the language
definition, as opposed to hehaving the way ordinary people would
expect or behaving the way that an embedded person doesn't like.
Very few aspects of C or C++ are "what ordinary people would
expect." You can get used to almost anything.
|
There are lots of reasons why C is an apalling language for embedded
development (and for virtually everything else), but unfortunately we're
stuck with it for most practical purposes.
|
|
| Back to top |
|
 |
|
|
|
|