On 05/07/2023 11:25, Martin Uecker wrote:
Am Mittwoch, dem 05.07.2023 um 11:11 +0200 schrieb David Brown:
On 05/07/2023 10:05, Rafał Pietrak via Gcc wrote:

...

In my personal opinion (which you are all free to disregard), named
address spaces were an interesting idea that failed.  I was
enthusiastic
about a number of the extensions in TR 18307 "C Extensions to support
embedded processors" when the paper was first published.  As I
learned
more, however, I saw it was a dead-end.  The features are too
under-specified to be useful or portable, gave very little of use to
embedded programmers, and fit badly with C.  It was an attempt to
standardise and generalise some of the mess of different extensions
that
proprietary toolchain developers had for a variety of 8-bit CISC
microcontrollers that could not use standard C very effectively.  But
it
was all too little, too late - and AFAIK none of these proprietary
toolchains support it.  GCC supports some of the features to some
extent
- a few named address spaces on a few devices, for "gnuc" only (not
standard C, and not C++), and has some fixed point support for some
targets (with inefficient generated code - it appears to be little
more
than an initial "proof of concept" implementation).

I do not think named address spaces have a future - in GCC or
anywhere
else.  The only real use of them at the moment is for the AVR for
accessing data in flash, and even then it is of limited success since
it
does not work in C++.

Can you explain a little bit why you think it is a dead-end?  It
seems an elegant solution to a range of problems to me.

Named address spaces are not standardised in C, and I do not expect they ever will be. The TR18307 document is not anywhere close to being of a quality that could be integrated with the C standards, even as optional features, and much of it makes no sense in practice (I have never heard of the IO stuff being implemented or used).

The few compilers that implement any of it do so in different ways - the "__flash" address space in AVR GCC is slightly different from the same extension in IAR's AVR compiler. For existing compilers, there is a strong inconsistency as to whether such things are "named address spaces", "extension keywords", "type qualifiers", "attributes", or other terms, all with subtly (or not so subtly) different effects on how they are used, what restrictions exist, conversions between types, and how errors can be diagnosed. Sometimes these features are considered part of the data type, sometimes of pointer types, sometimes they are just about data placement.

Since every compiler targeting these small awkward microcontrollers has a different idea of what something like "const __flash int x = 123;" means, and has been implementing their own ideas for a decade or two before TR18307 ever proposed "named address spaces", the TR hasn't a hope of being a real standard.

Named address spaces are not implemented at all, anywhere (AFAIK), for C++. (Some embedded toolchains have limited support for C++ on such microcontrollers, but these are again not really named address spaces.) Since C++ usage is heavily increasing in the small embedded system world, this is important. (GCC has much of the honour for that - as ARM took a bigger share of the market and GCC for ARM improved, the toolchain market was no longer at the mercy of big commercial vendors who charged absurd amounts for their C++ toolchains.) A feature which is only for C, and not supported by C++, is almost guaranteed to be dead-end.

And of course the type of processor for which named address spaces or other related extensions are essential, are a dying breed. The AVR is probably the only one with a significant future. Part of the appeal of ARM in the embedded world is it frees you from the pains of target-specific coding with some of your data in "near" memory, some in "extended" memory, some in "flash" address spaces or "IO" address spaces. It all works with standard C or C++. The same applies to challengers like RISC-V, MIPS, PPC, and any other core - you have a single flat address space for normal data.


I have no idea how much the GCC features are actually used,
but other compilers for  embedded systems such as SDCC also
support named address spaces.


And the targets supported by SDCC are also dead-end devices - there is not a single one of them that I would consider for a new project. These microcontrollers are now used almost exclusively for legacy projects - updates to existing hardware or software, and rely on compatibility with existing C extensions (whether they are called "named address spaces", "extension keywords", or anything else).


Now, there are things that I would like to be able to write in my code that could appear to be candidates for some kind of named address space. For example, I might want data that is placed in an external eeprom - it could be nice to be able to define, declare, read and write it like normal data in the code. But key to this would be the ability to define the way this works in /user/ code - named address spaces require changing the toolchain, which is out of the question in almost all use-cases. And it would spoil one of C's key advantages over alternative languages - to a fair extent (though not as completely as many people believe), you can guess what is happening from the code. You assume that "x = eeprom_var;" is small and efficient, while "x = read_eeprom(eeprom_var)" might take significant time to execute. People don't like hidden things in their C code.

It would be conceivable for GCC to add extensions that could be used to define your own named address spaces in user code. But doing so would require a lot of syntax and features that already exist in C++.

I would rather see better ways of controlling placement of data added to the compiler. In another post, I suggested allowing variable attributes - such as "section" - to be attached to types. I'd also like to see a way to specify the section name by compile-time evaluated code, not just a string literal. I'd like to be able to give sub-sections, and section flags in a convenient way. And - perhaps most importantly - I'd like to be able to use #pragma's to give sections for code or data for a block of code and data at a time, rather than having to specify it individually on each function. (That could perhaps also be done by allowing section attributes on namespaces in C++.)


David

Reply via email to