public inbox for gcc-help@gcc.gnu.org
 help / color / mirror / Atom feed
* const volatile
@ 2018-09-26 13:06 Kalamatee
  2018-09-26 13:10 ` Toby Douglass
                   ` (2 more replies)
  0 siblings, 3 replies; 8+ messages in thread
From: Kalamatee @ 2018-09-26 13:06 UTC (permalink / raw)
  To: gcc-help

Hi

I am wondering if there is a reason globals marked const volatile are put
into the data section and not read-only as const should imply?

I am trying to compile code for m68k AmigaOS which is resident using the
mathlib functions which need certain constants as volatile to prevent
incorrect sequence re-ordering in gcc's optimizations - however doing so
puts the value in bss data without const.

How can we have a global that is both volatile (to prevent incorrect
sequencing) and const (so it is read only and stored in read only data
section) ?

Thanks for any insight that may be provided.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: const volatile
  2018-09-26 13:06 const volatile Kalamatee
@ 2018-09-26 13:10 ` Toby Douglass
  2018-09-26 13:18 ` Xi Ruoyao
  2018-09-26 20:06 ` David Brown
  2 siblings, 0 replies; 8+ messages in thread
From: Toby Douglass @ 2018-09-26 13:10 UTC (permalink / raw)
  To: gcc-help

On 26/09/2018 14:54, Kalamatee wrote:
> Hi
> 
> I am wondering if there is a reason globals marked const volatile are put
> into the data section and not read-only as const should imply?

I have no clue as such, I know nothing about GCC internals, but 
read-only to me implies you could cache it and it would never change, 
which is not the case with volatile, as you're then indicating the value 
can change.

> I am trying to compile code for m68k AmigaOS

Woot!

> How can we have a global that is both volatile (to prevent incorrect
> sequencing)

Careful with that axe, Eugene.

I may be wrong, but I think volatile only indicates to the *compiler* 
that the value can change at any time.

However, *when* the value changes is down mainly to the hardware : you 
need to use load and store barriers appropriate, as also perhaps atomic 
writes (or the equivalent function thereof) to flush store buffers.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: const volatile
  2018-09-26 13:06 const volatile Kalamatee
  2018-09-26 13:10 ` Toby Douglass
@ 2018-09-26 13:18 ` Xi Ruoyao
  2018-09-26 20:06 ` David Brown
  2 siblings, 0 replies; 8+ messages in thread
From: Xi Ruoyao @ 2018-09-26 13:18 UTC (permalink / raw)
  To: Kalamatee, gcc-help

On 2018-09-26 13:54 +0100, Kalamatee wrote:
> Hi
> 
> I am wondering if there is a reason globals marked const volatile are
> put
> into the data section and not read-only as const should imply?
> 
> I am trying to compile code for m68k AmigaOS which is resident using
> the
> mathlib functions which need certain constants as volatile to prevent
> incorrect sequence re-ordering in gcc's optimizations - however doing
> so
> puts the value in bss data without const.
> 
> How can we have a global that is both volatile (to prevent incorrect
> sequencing) and const (so it is read only and stored in read only
> data
> section) ?

"const" means your program should not modify it.  "volatile" means
other things (invisible to your program) may modify it.

For example, a microcontroller's 8 input pins can be described as
"const volatile uint8_t mcu_input_1" in its C header.
-- 
Xi Ruoyao <xry111@mengyan1223.wang>
School of Aerospace Science and Technology, Xidian University

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: const volatile
  2018-09-26 13:06 const volatile Kalamatee
  2018-09-26 13:10 ` Toby Douglass
  2018-09-26 13:18 ` Xi Ruoyao
@ 2018-09-26 20:06 ` David Brown
       [not found]   ` <CAJWNc-4zQq3TD7RqesVbF6s6D=WSsWjSmYx7Jsw2x-0NjTFJfg@mail.gmail.com>
  2 siblings, 1 reply; 8+ messages in thread
From: David Brown @ 2018-09-26 20:06 UTC (permalink / raw)
  To: Kalamatee, gcc-help

On 26/09/18 14:54, Kalamatee wrote:
> Hi
> 
> I am wondering if there is a reason globals marked const volatile are put
> into the data section and not read-only as const should imply?
> 

"const" says /you/ promise not to change the value from your code.
"volatile" says that something else might change its value unknown to
the compiler.

It is rare to define "const volatile" variables.  It is usually more
useful to declare pointers to them.  They are used for things like
read-only hardware registers in microcontrollers, or for data that is
set from outside a program but is constant from within it (perhaps you
patch your binaries with a serial number, or a checksum - you could use
a pointer to const volatile for reading the number in the code).

The only real use of defined "const volatile" variables I have had is
for debugging - these would be variables that cannot be changed by the
code, but you might change them via a debugger.  Usually such things are
temporary during software development, and it's easier just to make them
normal volatile variables.

> I am trying to compile code for m68k AmigaOS which is resident using the
> mathlib functions which need certain constants as volatile to prevent
> incorrect sequence re-ordering in gcc's optimizations - however doing so
> puts the value in bss data without const.
> 

That is almost certainly not the best way to get the sequencing you
want.  Post more details on what you are trying to do, and I am sure
someone can give you advice.

> How can we have a global that is both volatile (to prevent incorrect
> sequencing) and const (so it is read only and stored in read only data
> section) ?

Why does it matter where the data is stored?

> 
> Thanks for any insight that may be provided.
> 

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: const volatile
       [not found]   ` <CAJWNc-4zQq3TD7RqesVbF6s6D=WSsWjSmYx7Jsw2x-0NjTFJfg@mail.gmail.com>
@ 2018-09-27  3:29     ` David Brown
       [not found]       ` <CAJWNc-6k-V0SfZzNq=HVJQZbpaZ63gQyvWGJ4oLeOTc0oTSu5Q@mail.gmail.com>
  0 siblings, 1 reply; 8+ messages in thread
From: David Brown @ 2018-09-27  3:29 UTC (permalink / raw)
  To: Kalamatee, gcc-help

(Please keep the gcc help list on the copies here - it saves duplication 
of answers, and means everyone gets to see them.)

On 26/09/2018 17:24, Kalamatee wrote:
> 
> 
> On Wed, 26 Sep 2018 at 16:00, David Brown <david@westcontrol.com 
> <mailto:david@westcontrol.com>> wrote:
> 
>     On 26/09/18 14:54, Kalamatee wrote:
>      > Hi
>      >
>      > I am wondering if there is a reason globals marked const volatile
>     are put
>      > into the data section and not read-only as const should imply?
>      >
> 
>     "const" says /you/ promise not to change the value from your code.
>     "volatile" says that something else might change its value unknown to
>     the compiler.
> 
>     It is rare to define "const volatile" variables.  It is usually more
>     useful to declare pointers to them.  They are used for things like
>     read-only hardware registers in microcontrollers, or for data that is
>     set from outside a program but is constant from within it (perhaps you
>     patch your binaries with a serial number, or a checksum - you could use
>     a pointer to const volatile for reading the number in the code).
> 
>     The only real use of defined "const volatile" variables I have had is
>     for debugging - these would be variables that cannot be changed by the
>     code, but you might change them via a debugger.  Usually such things are
>     temporary during software development, and it's easier just to make them
>     normal volatile variables.
> 
>      > I am trying to compile code for m68k AmigaOS which is resident
>     using the
>      > mathlib functions which need certain constants as volatile to prevent
>      > incorrect sequence re-ordering in gcc's optimizations - however
>     doing so
>      > puts the value in bss data without const.
>      >
> 
>     That is almost certainly not the best way to get the sequencing you
>     want.  Post more details on what you are trying to do, and I am sure
>     someone can give you advice.
> 
> 
> This comes from the standard sun mathlib code.
> 
> Here’s one example where it isn’t for the sequence but to cause a 
> controlled crash in the correct way -:
> https://github.com/ezrec/AROS-mirror/blob/ABI_V1/AROS/compiler/stdc/math/e_log.c
> 

I am not an expert in floating point details, especially not for 
non-finite things, but to my mind this code is clearly unnecessary.  The 
compiler will give the same result for "-two54 / vzero" whether vzero is 
declared "static const volatile double = 0.0;", or without the volatile, 
or given just as the literal 0.0 in the code.  Without the volatile, the 
code will be (marginally) shorter and faster as the construction of the 
infinity will be done at compile-time instead of run-time.

Wait for others to give an opinion before changing this, however.

> 
>      > How can we have a global that is both volatile (to prevent incorrect
>      > sequencing) and const (so it is read only and stored in read only
>     data
>      > section) ?
> 
>     Why does it matter where the data is stored?
> 
> 
> Because .data/.bss cannot exist in the rom image.

That is irrelevant.  If the "const volatile" variable has an explicit 
initialisation, it will be allocated to .data and initialised at startup 
just like any other initialised data variable.  If it is not explicitly 
initialised, it will be allocated to .bss and zeroed at startup - like 
any other uninitialised variable.

It is only from /your/ code - code run after "main()" starts - that 
"const" says you can't write to the variable.  The C startup code will 
initialise it as normal before main() starts.

> 
> 
>      >
>      > Thanks for any insight that may be provided.
>      >
> 

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: const volatile
       [not found]       ` <CAJWNc-6k-V0SfZzNq=HVJQZbpaZ63gQyvWGJ4oLeOTc0oTSu5Q@mail.gmail.com>
@ 2018-09-27  5:25         ` David Brown
  2018-09-28 14:31           ` Rob
  0 siblings, 1 reply; 8+ messages in thread
From: David Brown @ 2018-09-27  5:25 UTC (permalink / raw)
  To: Kalamatee, GCC help

Again - /please/ keep gcc-help@gcc.gnu.org in the "to" or "cc" list so 
that these mails go to mailing list.  This is a public discussion and 
help, not personal email.


On 26/09/18 18:11, Kalamatee wrote:
> 
> 
> On Wed, 26 Sep 2018 at 16:44, David Brown <david@westcontrol.com 
> <mailto:david@westcontrol.com>> wrote:
> 
>     (Please keep the gcc help list on the copies here - it saves
>     duplication
>     of answers, and means everyone gets to see them.)
> 
>     On 26/09/2018 17:24, Kalamatee wrote:
>      >
>      >
>      > On Wed, 26 Sep 2018 at 16:00, David Brown <david@westcontrol.com
>     <mailto:david@westcontrol.com>
>      > <mailto:david@westcontrol.com <mailto:david@westcontrol.com>>> wrote:
>      >
>      >     On 26/09/18 14:54, Kalamatee wrote:
>      >      > Hi
>      >      >
>      >      > I am wondering if there is a reason globals marked const
>     volatile
>      >     are put
>      >      > into the data section and not read-only as const should imply?
>      >      >
>      >
>      >     "const" says /you/ promise not to change the value from your
>     code.
>      >     "volatile" says that something else might change its value
>     unknown to
>      >     the compiler.
> 
> 
> That’s not ‘all’ it says. To be precise volatile tells the compiler that 
> the object is subject to sudden change for reasons which cannot be 
> predicted from a study of the program itself*, and forces every 
> reference to such an object to be a genuine reference.*

Yes, that is true.

> The second part is the important part - since it implies the compiler 
> will not optimize those references away - in the case in hand this means 
> zero is not optimized away resulting in the wrong/no exception being 
> generated.
> 

And that is not true.

The compiler needs to generate the same /defined/ effects for division 
by zero whether the zero is given as a literal constant in the code, or 
read in some way (such as from a volatile variable).  If an operation 
has /undefined/ effect - such as integer division by 0 - then there is 
no correct behaviour to expect regardless of where the 0 comes from. 
For floating point division, it depends on the compiler and some 
settings (I am not an expert here).  If the effects are defined, then 
they will be the same for a compile-time constant and a 0 loaded from a 
volatile - if not, there is a bug in the compiler.

> This is only one of the many places it is used in the math code for this 
> specific reason.
> 

I am confident that this is either unnecessary, or a work-around for 
compiler problems.  Others with more expertise on floating point errors 
can confirm or correct this.

> 
>      >
>      >     It is rare to define "const volatile" variables.  It is
>     usually more
>      >     useful to declare pointers to them.  They are used for things
>     like
>      >     read-only hardware registers in microcontrollers, or for data
>     that is
>      >     set from outside a program but is constant from within it
>     (perhaps you
>      >     patch your binaries with a serial number, or a checksum - you
>     could use
>      >     a pointer to const volatile for reading the number in the code).
>      >
>      >     The only real use of defined "const volatile" variables I
>     have had is
>      >     for debugging - these would be variables that cannot be
>     changed by the
>      >     code, but you might change them via a debugger.  Usually such
>     things are
>      >     temporary during software development, and it's easier just
>     to make them
>      >     normal volatile variables.
>      >
>      >      > I am trying to compile code for m68k AmigaOS which is resident
>      >     using the
>      >      > mathlib functions which need certain constants as volatile
>     to prevent
>      >      > incorrect sequence re-ordering in gcc's optimizations -
>     however
>      >     doing so
>      >      > puts the value in bss data without const.
>      >      >
>      >
>      >     That is almost certainly not the best way to get the
>     sequencing you
>      >     want.  Post more details on what you are trying to do, and I
>     am sure
>      >     someone can give you advice.
>      >
>      >
>      > This comes from the standard sun mathlib code.
>      >
>      > Here’s one example where it isn’t for the sequence but to cause a
>      > controlled crash in the correct way -:
>      >
>     https://github.com/ezrec/AROS-mirror/blob/ABI_V1/AROS/compiler/stdc/math/e_log.c
>      >
> 
>     I am not an expert in floating point details, especially not for
>     non-finite things, but to my mind this code is clearly unnecessary. 
>     The
>     compiler will give the same result for "-two54 / vzero" whether
>     vzero is
>     declared "static const volatile double = 0.0;", or without the
>     volatile,
>     or given just as the literal 0.0 in the code.  Without the volatile,
>     the
>     code will be (marginally) shorter and faster as the construction of the
>     infinity will be done at compile-time instead of run-time.
> 
>     Wait for others to give an opinion before changing this, however.
> 
>      >
>      >      > How can we have a global that is both volatile (to prevent
>     incorrect
>      >      > sequencing) and const (so it is read only and stored in
>     read only
>      >     data
>      >      > section) ?
>      >
>      >     Why does it matter where the data is stored?
>      >
>      >
>      > Because .data/.bss cannot exist in the rom image.
> 
>     That is irrelevant.
> 
> 
> It is not irrelevant.
> 
> if the value is const - it is put in .rodata but the code may be (and 
> does end up) optimized incorrectly.

"Incorrect optimisation" sounds like a compiler bug.  I think it is more 
likely that the situation is a bug in the code, or the programmer's 
expectations.

> if the value is volatile - it is put in the .bss section and the code is 
> always compiled correctly. however we can not use it in rom because 
> .bss/.data sections cannot be used there.

That is, as I say, irrelevant.

The compiler (or, more accurately, the implementation - including linker 
and C startup library) will ensure that the variable has the correct 
initialised value before main() (or any global constructors, for C++) is 
called.  It does not matter if the object containing the "0.0" value is 
in rom or in ram, as long as it has the correct value.

> 
>        If the "const volatile" variable has an explicit
>     initialisation, it will be allocated to .data and initialised at
>     startup
>     just like any other initialised data variable.  If it is not explicitly
>     initialised, it will be allocated to .bss and zeroed at startup - like
>     any other uninitialised variable.
> 
>     It is only from /your/ code - code run after "main()" starts - that
>     "const" says you can't write to the variable.  The C startup code will
>     initialise it as normal before main() starts.
> 
> 
> I understand what you are saying fine - and I'm sorry if it seems I am 
> being argumentative - but it still sounds like the compiler is doing the 
> wrong thing when it knows from "const" that the data is to be read only. 

The compiler is not doing the wrong thing.  "const" does /not/ mean that 
the data is read only - it means that /you/ are not allowed to change 
it.  If the compiler also knows that it has full control of the variable 
- as is normally the case - then it knows a "const" variable can be put 
in rom data to save a little memory and perhaps improve cache locality. 
If the compiler knows that it does /not/ have full control - as is the 
case for a "volatile" - it will put it in modifiable ram.  That is where 
you would normally want your volatile variables, whether they are marked 
"const" or not.

> My only interest is in getting the issue resolved "correctly".
> 
> For now I guess I will have to add the section attribute to all constant 
> volatiles to force the correct thing to happen.

Have you actually checked to see if something is failing to work 
correctly?  As far as I can see, that could only happen if your system 
is otherwise broken and failing to correctly initialise the data 
section.  Have you checked that what you /think/ should happen is 
actually correctly defined behaviour, rather than just something that 
happens to be the case on some targets or some circumstances?

Have you looked at other solutions, such putting the zero in read-only 
memory as a normal "const" variable, and then using a forced volatile 
read of it?  ACCESS_ONCE from Linux helps for that:

	#define ACCESS_ONCE(v) *((volatile typeof((v)) *) &(v))

Have you looked at what happens if you use 0.0 instead of this "volatile 
const", to see that it is in some way necessary?


As I say, I am not an expert on floating point errors.  But my feeling 
here is that you will get exactly the same results in all cases - which 
may not be the results you think you should get.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: const volatile
  2018-09-27  5:25         ` David Brown
@ 2018-09-28 14:31           ` Rob
  2018-09-29  9:23             ` Andrew Haley
  0 siblings, 1 reply; 8+ messages in thread
From: Rob @ 2018-09-28 14:31 UTC (permalink / raw)
  To: david; +Cc: kalamatee, gcc

On Wed, 26 Sep 2018 at 21:06, David Brown <david@westcontrol.com> wrote:
> On 26/09/18 18:11, Kalamatee wrote:
> > On Wed, 26 Sep 2018 at 16:44, David Brown <david@westcontrol.com
> > <mailto:david@westcontrol.com>> wrote:
> >     On 26/09/2018 17:24, Kalamatee wrote:
> >      > On Wed, 26 Sep 2018 at 16:00, David Brown <david@westcontrol.com
> >     <mailto:david@westcontrol.com>
> >      > <mailto:david@westcontrol.com <mailto:david@westcontrol.com>>> wrote:
> >      >
> >      >     On 26/09/18 14:54, Kalamatee wrote:
> >      >      > Hi
> >      >      >
> >      >      > I am wondering if there is a reason globals marked const
> >     volatile
> >      >     are put
> >      >      > into the data section and not read-only as const should imply?
> >      >      >
> >      >
> >      >     "const" says /you/ promise not to change the value from your
> >     code.
> >      >     "volatile" says that something else might change its value
> >     unknown to
> >      >     the compiler.
> >
> >
> > That’s not ‘all’ it says. To be precise volatile tells the compiler that
> > the object is subject to sudden change for reasons which cannot be
> > predicted from a study of the program itself*, and forces every
> > reference to such an object to be a genuine reference.*
>
> > My only interest is in getting the issue resolved "correctly".
> >
> > For now I guess I will have to add the section attribute to all constant
> > volatiles to force the correct thing to happen.
>
> ...
>
> Have you looked at what happens if you use 0.0 instead of this "volatile
> const", to see that it is in some way necessary?
>
>
> As I say, I am not an expert on floating point errors.  But my feeling
> here is that you will get exactly the same results in all cases - which
> may not be the results you think you should get.
>

If it helps, this is likely related to a bugfix that went into freebsd's libm a
while back after they switched to clang. I can't remember the details, but I
believe the bug was to do with clang incorrectly constant-folding floating
point expressions in the wrong rounding mode, or perhaps how it interacted with
fesetround() and the fenv access pragmas.

The mirror here [1] shows the fix.

-
Rob

1: https://github.com/freebsd/freebsd/commit/e7b0a63c190c7ecb475b09f41387a75952540f49

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: const volatile
  2018-09-28 14:31           ` Rob
@ 2018-09-29  9:23             ` Andrew Haley
  0 siblings, 0 replies; 8+ messages in thread
From: Andrew Haley @ 2018-09-29  9:23 UTC (permalink / raw)
  To: Rob, david; +Cc: kalamatee, gcc

On 09/28/2018 01:03 PM, Rob wrote:
> If it helps, this is likely related to a bugfix that went into freebsd's libm a
> while back after they switched to clang. I can't remember the details, but I
> believe the bug was to do with clang incorrectly constant-folding floating
> point expressions in the wrong rounding mode, or perhaps how it interacted with
> fesetround() and the fenv access pragmas.
> 
> The mirror here [1] shows the fix.

Yeah, I see. It's about setting the flags in the FPU so that the
division by zero is delayed to runtime rather than evaluated as
a constant by the compiler.

-		return -two25/zero;		/* log(+-0)=-inf */
+		return -two25/vzero;		/* log(+-0)=-inf */

-- 
Andrew Haley
Java Platform Lead Engineer
Red Hat UK Ltd. <https://www.redhat.com>
EAC8 43EB D3EF DB98 CC77 2FAD A5CD 6035 332F A671

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2018-09-28 14:20 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-09-26 13:06 const volatile Kalamatee
2018-09-26 13:10 ` Toby Douglass
2018-09-26 13:18 ` Xi Ruoyao
2018-09-26 20:06 ` David Brown
     [not found]   ` <CAJWNc-4zQq3TD7RqesVbF6s6D=WSsWjSmYx7Jsw2x-0NjTFJfg@mail.gmail.com>
2018-09-27  3:29     ` David Brown
     [not found]       ` <CAJWNc-6k-V0SfZzNq=HVJQZbpaZ63gQyvWGJ4oLeOTc0oTSu5Q@mail.gmail.com>
2018-09-27  5:25         ` David Brown
2018-09-28 14:31           ` Rob
2018-09-29  9:23             ` Andrew Haley

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).