Date: Fri, 14 Nov 2025 18:41:09 +0100
On 14/11/2025 16:59, Frederick Virchanza Gotham via Std-Proposals wrote:
> On Fri, Nov 14, 2025 at 3:13 PM David Brown wrote:
>>
>> Flash is almost never directly writeable at run-time. Special
>> procedures, well outside the scope of the C++ standards, are used to
>> erase and write flash memory. There are certain other types of
>> non-volatile memory that can be written directly, but not flash.
>
>
>
> In my last job programming microscopes, there was a Texas Instruments
> microcontroller connected by I2C to an Arduino microcontroller.
>
> I wrote a program for the Texas to send packets over I2C containing a
> firmware upgrade for the Arduino.
> I wrote a program for the Arduino to receive packets over I2C and to
> write to its own Flash.
>
> I got this working. Arduino's can write to their own Flash at runtime
> (so long as you don't overwrite the machine code that's currently
> being executed). Or at least the SAMD21 can. Maybe others can't.
>
You are referring to the "special procedures" I mention. Flash is /not/
read-write, the way RAM is. It is basically read-only, but you can
erase blocks and you can re-write blocks. There is considerable
variation in the size of the blocks you can erase at a time, and the
size of blocks that you can write at a time. Some flash can be
overwritten without erasing, but then you can only change blank bits
(logic 1 for NOR flash) to programmed bits (logic 0 for NOR flash).
Some flash takes a long time for erasing or programming, others can do
so quickly. All that is common for flash is that you can (usually) read
it easily, albeit more slowly than fast ram, and that changing it is a
complex matter.
Handling of flash is not something that belongs in a discussion about
C++ standards.
>
>
>> const objects that do not have static storage duration and program
>> lifetimes, cannot be placed in flash because their address and contents
>> are not fixed when the program image is created (i.e., at compile/link
>> time).
>
>
>
> I'm talking about the programmer deliberately placing a const object
> in the Flash at a known address.
Then you are not talking about C++. C++ does not deal with fixed, known
addresses.
It can definitely be useful to specify bits of data (and occasionally
code) at fixed addresses in a microcontroller. I do that regularly. It
is typically done using compiler extensions that may depend on the exact
target, combined with linker settings that are outside of the scope of
C++. Some people prefer to use assembly, or perhaps other external
tools for generating "absolute" segments. There are a number of
methods, and none of them are relevant to standard C++.
>
> Like if the flash is from 0x2000 to 0x8000, then at runtime I can
> store an object at 0x4000. Later after I reset the microcontroller,
> that object will still be there at address 0x4000 and I can invoke
> const methods on it -- just so long as it doesn't contain any
> mutables.
Declare your object as "const" with static storage duration, and unless
you have messed up your linker configuration or have a very strange
compiler, the data will be in a read-only section and linked into flash
as long as the compiler knows the data cannot be changed. You don't
need to detect mutable members - the compiler handles that.
There is an exception here, since you mentioned Arduinos - the AVR
microcontrollers have distinct address spaces for flash and ram, meaning
they use different processor instructions for accessing those memories.
Since you can always add or remove "const" qualifiers to pointers, AVR
compilers often place "const" data in ram and require compiler
extensions (such as a "__flash" qualifier) to put data into flash.
Since version 14, gcc has been much better at putting const data into
flash, with certain complications and limitations.
>
> But I'm not only talking about microcontrollers here. On desktop PC's,
> you can create an object and then change the permissions on the page
> of memory to read-only.
Doing that is outside the scope of C++ standards - it's in the realm of
OS calls.
If you want to have a trait for detecting if a class contains mutable
members, I don't see any issues with that. I can imagine that it could
be useful to know if an object is always bitwise immutable rather than
just logically constant. For example, it means a hash of the underlying
bytes would give consistent results (although padding might complicate
that). And I can imagine it could be combined with reflection in
various ways.
My objection is that you think this is connected to flash,
microcontrollers, read-only data, or changing flash. It is not. At
most, it could give programmers a way to have a static assertion on
whether a given class instance - declared "const" and "constinit", and
with static storage duration - will likely be placed in flash or not.
However, in practice programmers who need to be sure an item is in
flash, especially if it is to be at a particular location, already know
exactly what the type is and if it is suitable for the task.
> On Fri, Nov 14, 2025 at 3:13 PM David Brown wrote:
>>
>> Flash is almost never directly writeable at run-time. Special
>> procedures, well outside the scope of the C++ standards, are used to
>> erase and write flash memory. There are certain other types of
>> non-volatile memory that can be written directly, but not flash.
>
>
>
> In my last job programming microscopes, there was a Texas Instruments
> microcontroller connected by I2C to an Arduino microcontroller.
>
> I wrote a program for the Texas to send packets over I2C containing a
> firmware upgrade for the Arduino.
> I wrote a program for the Arduino to receive packets over I2C and to
> write to its own Flash.
>
> I got this working. Arduino's can write to their own Flash at runtime
> (so long as you don't overwrite the machine code that's currently
> being executed). Or at least the SAMD21 can. Maybe others can't.
>
You are referring to the "special procedures" I mention. Flash is /not/
read-write, the way RAM is. It is basically read-only, but you can
erase blocks and you can re-write blocks. There is considerable
variation in the size of the blocks you can erase at a time, and the
size of blocks that you can write at a time. Some flash can be
overwritten without erasing, but then you can only change blank bits
(logic 1 for NOR flash) to programmed bits (logic 0 for NOR flash).
Some flash takes a long time for erasing or programming, others can do
so quickly. All that is common for flash is that you can (usually) read
it easily, albeit more slowly than fast ram, and that changing it is a
complex matter.
Handling of flash is not something that belongs in a discussion about
C++ standards.
>
>
>> const objects that do not have static storage duration and program
>> lifetimes, cannot be placed in flash because their address and contents
>> are not fixed when the program image is created (i.e., at compile/link
>> time).
>
>
>
> I'm talking about the programmer deliberately placing a const object
> in the Flash at a known address.
Then you are not talking about C++. C++ does not deal with fixed, known
addresses.
It can definitely be useful to specify bits of data (and occasionally
code) at fixed addresses in a microcontroller. I do that regularly. It
is typically done using compiler extensions that may depend on the exact
target, combined with linker settings that are outside of the scope of
C++. Some people prefer to use assembly, or perhaps other external
tools for generating "absolute" segments. There are a number of
methods, and none of them are relevant to standard C++.
>
> Like if the flash is from 0x2000 to 0x8000, then at runtime I can
> store an object at 0x4000. Later after I reset the microcontroller,
> that object will still be there at address 0x4000 and I can invoke
> const methods on it -- just so long as it doesn't contain any
> mutables.
Declare your object as "const" with static storage duration, and unless
you have messed up your linker configuration or have a very strange
compiler, the data will be in a read-only section and linked into flash
as long as the compiler knows the data cannot be changed. You don't
need to detect mutable members - the compiler handles that.
There is an exception here, since you mentioned Arduinos - the AVR
microcontrollers have distinct address spaces for flash and ram, meaning
they use different processor instructions for accessing those memories.
Since you can always add or remove "const" qualifiers to pointers, AVR
compilers often place "const" data in ram and require compiler
extensions (such as a "__flash" qualifier) to put data into flash.
Since version 14, gcc has been much better at putting const data into
flash, with certain complications and limitations.
>
> But I'm not only talking about microcontrollers here. On desktop PC's,
> you can create an object and then change the permissions on the page
> of memory to read-only.
Doing that is outside the scope of C++ standards - it's in the realm of
OS calls.
If you want to have a trait for detecting if a class contains mutable
members, I don't see any issues with that. I can imagine that it could
be useful to know if an object is always bitwise immutable rather than
just logically constant. For example, it means a hash of the underlying
bytes would give consistent results (although padding might complicate
that). And I can imagine it could be combined with reflection in
various ways.
My objection is that you think this is connected to flash,
microcontrollers, read-only data, or changing flash. It is not. At
most, it could give programmers a way to have a static assertion on
whether a given class instance - declared "const" and "constinit", and
with static storage duration - will likely be placed in flash or not.
However, in practice programmers who need to be sure an item is in
flash, especially if it is to be at a particular location, already know
exactly what the type is and if it is suitable for the task.
Received on 2025-11-14 17:41:16
