EmbeddedRelated.com
Forums
The 2024 Embedded Online Conference

C++, Ada, ...

Started by pozz April 17, 2021
On 18/04/2021 09:39, Niklas Holsti wrote:
> On 2021-04-17 19:45, David Brown wrote: >> On 17/04/2021 17:48, pozz wrote: >>> What do you think about different languages than usual C for embedded >>> systems? >>> >>> I mean C++, Ada but also Python. Always more powerful embedded >>> processors are coming, so I expect new and modern languages will enter >>> in the embedded world. >>> >>> ... >>> Is it ok for me to study and learn new things... but it will be more >>> difficult to acquire new skills for real jobs. >>> >>> What do you think? >> >> � ... >> Ada involves a fair amount of change to how you work, compared to C >> development.� (Disclaimer - I have only done a very small amount of Ada >> coding, and no serious projects.� But I have considered it as an >> option.)� I really don't see it becoming much more common, and outside >> of niche areas (defence, aerospace) it is very rare.� Programming in Ada >> often takes a lot more effort even for simple things, leading quickly to >> code that is so wordy that it is unclear what is going on. > > > That depends, I guess, on what one considers "simple", and also, of > course, on how familiar one is with the languages. > > Perhaps it is time to link once again to the experience of C versus Ada > in an introductory embedded-programming class using a model rail-road > example, where the students using Ada fared much better than those using C: > > http://archive.adaic.com/projects/atwork/trains.html
Are there no newer examples? While this study was interesting, it is some 30 years out of date and compares and old version of Ada with an old version of C (perhaps not even C90). I'd rather see the pros and cons of Ada 2012 compared to C++17.
> > I am (as you guessed) an Ada fan, and find it a pleasure to write, even > if it takes more keystrokes than the equivalent in C.
I had no need to guess - it's not the first time you have posted about Ada here! I'm glad that someone with your Ada qualifications can chime in here, and can correct my if I'm wrong.
> > For embedded systems in particular, I find portability to be a great > advantage of Ada. With few exceptions, the embedded program can be > exercised on the development host, and if the target supports the > standard Ada tasking system (or a subset of it), this applies even to > multi-threaded programs (without the need to emulate some embedded > RTK/OS on the host). >
For suitable targets, I can see that being useful. C and C++ can be used on a wider range of targets, and with a wider range of RTOS (if any). Of course, code for widely differing target systems is often very different anyway, so portability is not always a concern.
> >> And most of the advantages of Ada (such as better typing) can be >> achieved in C++ with less effort, > > According to the link above, the main Ada advantage was the ability to > define one's own problem-oriented scalar types, such as integers with > specific value ranges. AIUI, this is not easily done in C++. >
Sure it can be done in C++. <https://foonathan.net/2016/10/strong-typedefs/> You can make types with specific ranges (with compile-time checks where possible, optional run-time checks otherwise). You can choose which operations you allow on them, and how they combine (so that multiplying a speed and a time give you a distance automatically, but adding them is not allowed). You can make integer types with different overflow behaviour (wrapping, saturating, throwing errors, unspecified behaviour, undefined behaviour) that can be used as easily as normal integers, and mixed if and only if it is safe to do so or you make it explicit. You can make array types that are indexed by enumerated types. It's all possible - more so that in Ada, AFAIK. Where you have a difference, however, is that many of the most beneficial cases (such as strong subrange types) are simple to use in Ada and built into the language, and therefore they are often used. In C++, you need to find a suitable template library or make things yourself, giving a much higher barrier to use. A very interesting distinction when looking at language features and safe coding is how much people /could/ use safety features, and how much they /do/ use them. For example, with C programming you can get strong type safety as long as you wrap all your new types in structs. The compiler will complain for type mistakes, just as it would in Ada - but the /use/ of such types is often very inconvenient in C.
> >> and at the same time C++ can give additional safety on >> resources that is harder to get on Ada.&#4294967295; (But Ada has some nice features >> introspective that C++ programmers currently only dream about.) > > > Can you be more specific on those points, please? >
For the first point - my understanding is that in Ada, when you have classes you need to manually call constructor and destructor (initializer and finalizer) functions. RAII is thus harder, and it is as easy to make mistakes as it is in C (with malloc and free). Does Ada have the equivalent of std::unique_ptr, std::shared_ptr and other smart pointers, or container classes that handle allocation? For the second point, I am thinking of things like type attributes. I would /really/ like C++ enumerations to have something matching the "first" and "last" attributes! AFAIK, C++ won't get this until reflection is added, probably not until C++26.
> >> It used to be the case that C++ compilers were expensive and poor >> quality, that the resulting code was very slow on common >> microcontrollers, and that the language didn't have much extra to offer >> small-systems embedded developers.&#4294967295; That, I think, has changed in all >> aspects.&#4294967295; I use gcc 10 with C++17 on Cortex-M devices, and features like >> templates, strong enumerations, std::array, and controlled automatic >> conversions make it easier to write good code. > > > AdaCore provides the gcc-based GNAT Ada compiler for several embedded > targets, free to use for open-source projects: libre.adacore.com. > > Commercial projects can use Ada on other targets by means of the > (different) AdaCore compiler that generates C code as an intermediate > representation. >
This means that Ada suffers from a similar barrier to adoption that C++ used to do. Big companies will happily pay the cost for the tools that they think will lead to better development efficiency or reliability. Smaller ones will have a much harder time trying to justify the expense, especially as they will often have few developers who can use the tools. A move from C to Ada is compounded by needing a complete change of the code - with C to C++, you can re-use old code, and you can also use a few of the C++ features rather than moving wholescale (though of course you also miss out on corresponding benefits).
On 2021-04-18 13:53, David Brown wrote:
> On 17/04/2021 20:55, Tom Gardner wrote: >> On 17/04/21 17:45, David Brown wrote: >>> And most of >>> the advantages of Ada (such as better typing) can be achieved in C++ >>> with less effort, and at the same time C++ can give additional safety on >>> resources that is harder to get on Ada. >> >> Interesting. Could you give a quick outline of that? >> > > Which part? > > My understanding of Ada classes is that, like Pascal classes, you need > to explicitly construct and destruct objects. This gives far greater > scope for programmers to get things wrong than when they are handled > automatically by the language.
If you mean automatic allocation and deallocation of storage, Ada lets you define types that have an "initializer" that is called automatically, and can allocate memory if it needs to, and a "finalizer" that is automatically called when leaving the scope of the object in question. The finalizer does have to explicitly deallocate any explicitly allocated and owned resources, and it may have to use reference counting for that, for complex data structures. AUI that also holds for C++, although I believe recent C++ standards may have simplified the definition and use of reference-counted data structures.
> On the other hand, some of Ada's type mechanisms make it a lot easier to > make new types with similar properties while remaining distinct (such as > subranges of integer types). You can do that in C++, but someone needs > to make the effort to make the appropriate class templates. Thus these > are more often used in Ada coding than in C++ coding.
(That relative ease in Ada was the point of my other response -- more to come on that.)
> On the third hand (three hands are always useful for programming), the > wordy nature of type conversions in Ada mean programmers would be > tempted to take shortcuts and skip these extra types.
Huh? A normal conversion in C is written "(newtype)expression", the same in Ada is written "newtype(expression)". Exactly the same number of characters, only the placement of the () is different. The C form might even require an extra set of parentheses around it, to demarcate the expression to be converted from any containing expression. Of course, in C you have implicit conversions between all kinds of numerical types, often leading to a whole lot of errors... not only apples+oranges, but also truncation or other miscomputation.
On 2021-04-18 15:59, David Brown wrote:
> On 18/04/2021 09:39, Niklas Holsti wrote: >> On 2021-04-17 19:45, David Brown wrote: >>> On 17/04/2021 17:48, pozz wrote: >>>> What do you think about different languages than usual C for embedded >>>> systems? >>>> >>>> I mean C++, Ada but also Python. Always more powerful embedded >>>> processors are coming, so I expect new and modern languages will enter >>>> in the embedded world. >>>> >>>> ... >>>> Is it ok for me to study and learn new things... but it will be more >>>> difficult to acquire new skills for real jobs. >>>> >>>> What do you think? >>> >>> &#4294967295; ... >>> Ada involves a fair amount of change to how you work, compared to C >>> development.&#4294967295; (Disclaimer - I have only done a very small amount of Ada >>> coding, and no serious projects.&#4294967295; But I have considered it as an >>> option.)&#4294967295; I really don't see it becoming much more common, and outside >>> of niche areas (defence, aerospace) it is very rare.&#4294967295; Programming in Ada >>> often takes a lot more effort even for simple things, leading quickly to >>> code that is so wordy that it is unclear what is going on. >> >> >> That depends, I guess, on what one considers "simple", and also, of >> course, on how familiar one is with the languages. >> >> Perhaps it is time to link once again to the experience of C versus Ada >> in an introductory embedded-programming class using a model rail-road >> example, where the students using Ada fared much better than those using C: >> >> http://archive.adaic.com/projects/atwork/trains.html > > Are there no newer examples?
I have none to hand, at least.
> While this study was interesting, it is some 30 years out of date
I would call it "30 years old". Whether it is "out of date" can be debated -- I don't think the basic ideas of the two languages have changed very drastically even in that time.
> and compares and old version of Ada with an old version of C (perhaps > not even C90). I'd rather see the pros and cons of Ada 2012 compared > to C++17.
So would I, but I haven't seen any such studies reported. I can only point to the biased material at https://www.adaic.org/advantages/. And a recent Ada-adoption story from NVIDIA: https://www.adacore.com/webinars/securing-future-of-embedded-software but that is more about the AdaCore tools and the SPARK form of Ada than about C-vs-Ada.
>> >> I am (as you guessed) an Ada fan, and find it a pleasure to write, even >> if it takes more keystrokes than the equivalent in C. > > I had no need to guess - it's not the first time you have posted about > Ada here! I'm glad that someone with your Ada qualifications can chime > in here, and can correct my if I'm wrong. > >> >> For embedded systems in particular, I find portability to be a great >> advantage of Ada. With few exceptions, the embedded program can be >> exercised on the development host, and if the target supports the >> standard Ada tasking system (or a subset of it), this applies even to >> multi-threaded programs (without the need to emulate some embedded >> RTK/OS on the host). >> > > For suitable targets, I can see that being useful. C and C++ can be > used on a wider range of targets, and with a wider range of RTOS (if > any).
Ada can be used with other RTOSses too, although one loses both some ease-of-use advantages and the portability advantage. Typical Ada compilers for embedded systems also let one write Ada programs that do not need an RTOS at all and run with a single thread.
> Of course, code for widely differing target systems is often very > different anyway, so portability is not always a concern. > >> >>> And most of the advantages of Ada (such as better typing) can be >>> achieved in C++ with less effort, >> >> According to the link above, the main Ada advantage was the ability to >> define one's own problem-oriented scalar types, such as integers with >> specific value ranges. AIUI, this is not easily done in C++. >> > > Sure it can be done in C++. > > <https://foonathan.net/2016/10/strong-typedefs/>
I did not see any mention of range-checked types there. But yes, they can be constructed in C++, but not as easily as in Ada, as it seems we agree. I should have said "/as/ easily" in the quote above.
> You can make types with specific ranges (with compile-time checks where > possible, optional run-time checks otherwise). You can choose which > operations you allow on them, and how they combine (so that multiplying > a speed and a time give you a distance automatically, but adding them is > not allowed). You can make integer types with different overflow > behaviour (wrapping, saturating, throwing errors, unspecified behaviour, > undefined behaviour) that can be used as easily as normal integers, and > mixed if and only if it is safe to do so or you make it explicit. You > can make array types that are indexed by enumerated types. It's all > possible - more so that in Ada, AFAIK.
I admit that C++ templates allow the programming of more compile-time activities than Ada allows.
> Where you have a difference, however, is that many of the most > beneficial cases (such as strong subrange types) are simple to use in > Ada and built into the language, and therefore they are often used. In > C++, you need to find a suitable template library or make things > yourself, giving a much higher barrier to use.
Yup.
> A very interesting distinction when looking at language features and > safe coding is how much people /could/ use safety features, and how much > they /do/ use them. For example, with C programming you can get strong > type safety as long as you wrap all your new types in structs. The > compiler will complain for type mistakes, just as it would in Ada - but > the /use/ of such types is often very inconvenient in C.
Indeed.
>>> and at the same time C++ can give additional safety on >>> resources that is harder to get on Ada.&#4294967295; (But Ada has some nice features >>> introspective that C++ programmers currently only dream about.) >> >> >> Can you be more specific on those points, please? >> > > For the first point - my understanding is that in Ada, when you have > classes you need to manually call constructor and destructor > (initializer and finalizer) functions. RAII is thus harder, and it is > as easy to make mistakes as it is in C (with malloc and free). Does Ada > have the equivalent of std::unique_ptr, std::shared_ptr and other smart > pointers, or container classes that handle allocation?
Answered in another message. The Ada "controlled" types have automatically called initializer and finalizer operations. They can be used to implement smart pointers, but no smart pointers are built into Ada (perhaps mainly because they would then have to be thread-safe, which would be a lot of overhead for a single-threaded program).
> For the second point, I am thinking of things like type attributes. I > would /really/ like C++ enumerations to have something matching the > "first" and "last" attributes! AFAIK, C++ won't get this until > reflection is added, probably not until C++26.
Yes, good point in favour of Ada. I've seen some C++ programs that go to great metaprogramming lengths to define "trait" templates to get the equivalent of the "first", "last", "size" etc. attributes. So it is, again, possible in C++, but not as easy as when it is built-in, as in Ada.
>>> It used to be the case that C++ compilers were expensive and poor >>> quality, that the resulting code was very slow on common >>> microcontrollers, and that the language didn't have much extra to offer >>> small-systems embedded developers.&#4294967295; That, I think, has changed in all >>> aspects.&#4294967295; I use gcc 10 with C++17 on Cortex-M devices, and features like >>> templates, strong enumerations, std::array, and controlled automatic >>> conversions make it easier to write good code. >> >> >> AdaCore provides the gcc-based GNAT Ada compiler for several embedded >> targets, free to use for open-source projects: libre.adacore.com. >> >> Commercial projects can use Ada on other targets by means of the >> (different) AdaCore compiler that generates C code as an intermediate >> representation. >> > > This means that Ada suffers from a similar barrier to adoption that C++ > used to do. Big companies will happily pay the cost for the tools that > they think will lead to better development efficiency or reliability. > Smaller ones will have a much harder time trying to justify the expense, > especially as they will often have few developers who can use the tools. > A move from C to Ada is compounded by needing a complete change of the > code - with C to C++, you can re-use old code, and you can also use a > few of the C++ features rather than moving wholescale (though of course > you also miss out on corresponding benefits).
Of course you can move from C to Ada without a full re-write, because all Ada compilers provide inter-linking with C code, and most data structures can be mapped between the two languages. (For some Ada compilers like GNAT, this even holds for C++ and Ada) In fact, there is another C-vs-Ada study, http://archive.adaic.com/intro/ada-vs-c/cada_art.html where an Ada compiler vendor incrementally moved their Ada compiler from being written in C to being written in Ada, and found a steady increase of quality and decrease of cost-to-repair as modules were moved from C to Ada. But it is from 1995, so perhaps "out of date" :-)
On 18/04/2021 17:48, Niklas Holsti wrote:
> On 2021-04-18 13:53, David Brown wrote: >> On 17/04/2021 20:55, Tom Gardner wrote: >>> On 17/04/21 17:45, David Brown wrote: >>>> And most of >>>> the advantages of Ada (such as better typing) can be achieved in C++ >>>> with less effort, and at the same time C++ can give additional >>>> safety on >>>> resources that is harder to get on Ada. >>> >>> Interesting. Could you give a quick outline of that? >>> >> >> Which part? >> >> My understanding of Ada classes is that, like Pascal classes, you need >> to explicitly construct and destruct objects.&#4294967295; This gives far greater >> scope for programmers to get things wrong than when they are handled >> automatically by the language. > > > If you mean automatic allocation and deallocation of storage, Ada lets > you define types that have an "initializer" that is called > automatically, and can allocate memory if it needs to, and a "finalizer" > that is automatically called when leaving the scope of the object in > question. The finalizer does have to explicitly deallocate any > explicitly allocated and owned resources, and it may have to use > reference counting for that, for complex data structures.
I had a little look for this (these discussions are great for inspiring learning!). The impression I got was that it was possible, but what takes a few lines of C++ (excluding whatever work must be done inside the constructor and destructor bodies) involves inheriting from a specific library type. And you don't have automatic initialisation of subobjects and ancestors in a controlled order, nor automatic finalisation of them in the reverse order. Let's take a little example. And since this is comp.arch.embedded, let's take a purely embedded example of disabling interrupts, rather than shunned dynamic memory allocations: static inline uint32_t disableGlobalInterrupts(void) { uint32_t pri; asm volatile( " mrs %[pri], primask\n\t" // Get old mask " cpsid i\n\t" // Disable interrupts entirely " dsb" // Ensures that this takes effect before next // instruction : [pri] "=r" (pri) :: "memory"); return pri; } static inline void restoreGlobalInterrupts(uint32_t pri) { asm volatile( " msr primask, %[pri]" // Restore old mask :: [pri] "r" (pri) : "memory"); } class CriticalSectionLock { private : uint32_t oldpri; public : CriticalSectionLock() { oldpri = disableGlobalInterrupts(); } ~CriticalSectionLock() { restoreGlobalInterrupts(oldpri); } }; You can use it like this: bool compare_and_swap64(uint64_t * p, uint64_t old, uint64_t x) { CriticalSectionLock lock; if (*p != old) return false; *p = x; return true; } This is the code compiled for a 32-bit Cortex-M device: <https://godbolt.org/z/7KM9M6Kcd> The use of the class here has no overhead compared to manually disabling and re-enabling interrupts. What would be the Ada equivalent of this class, and of the "compare_and_swap64" function?
> > AUI that also holds for C++, although I believe recent C++ standards may > have simplified the definition and use of reference-counted data > structures. > > >> On the other hand, some of Ada's type mechanisms make it a lot easier to >> make new types with similar properties while remaining distinct (such as >> subranges of integer types).&#4294967295; You can do that in C++, but someone needs >> to make the effort to make the appropriate class templates.&#4294967295; Thus these >> are more often used in Ada coding than in C++ coding. > > > (That relative ease in Ada was the point of my other response -- more to > come on that.) > > >> On the third hand (three hands are always useful for programming), the >> wordy nature of type conversions in Ada mean programmers would be >> tempted to take shortcuts and skip these extra types. > > > Huh? A normal conversion in C is written "(newtype)expression", the same > in Ada is written "newtype(expression)". Exactly the same number of > characters, only the placement of the () is different. The C form might > even require an extra set of parentheses around it, to demarcate the > expression to be converted from any containing expression. > > Of course, in C you have implicit conversions between all kinds of > numerical types, often leading to a whole lot of errors... not only > apples+oranges, but also truncation or other miscomputation.
C also makes explicit conversions wordy, yes. In C++, you can choose which conversions are explicit and which are implicit - done carefully, your safe conversions will be implicit and unsafe ones need to be explicit. (C++ suffers from its C heritage and backwards compatibility, meaning it can't fix things that were always implicit conversion. It's too late to make "int x = 123.4;" an error. The best C++ can do is add a new syntax with better safety - so "int y { 123 };" is fine but "int z { 123.4 };" is an error.)
On 18/04/2021 18:23, Niklas Holsti wrote:
> On 2021-04-18 15:59, David Brown wrote: >> On 18/04/2021 09:39, Niklas Holsti wrote: >>> On 2021-04-17 19:45, David Brown wrote: >>>> On 17/04/2021 17:48, pozz wrote: >>>>> What do you think about different languages than usual C for embedded >>>>> systems? >>>>> >>>>> I mean C++, Ada but also Python. Always more powerful embedded >>>>> processors are coming, so I expect new and modern languages will enter >>>>> in the embedded world. >>>>> >>>>> ... >>>>> Is it ok for me to study and learn new things... but it will be more >>>>> difficult to acquire new skills for real jobs. >>>>> >>>>> What do you think? >>>> >>>> &#4294967295;&#4294967295; ... >>>> Ada involves a fair amount of change to how you work, compared to C >>>> development.&#4294967295; (Disclaimer - I have only done a very small amount of Ada >>>> coding, and no serious projects.&#4294967295; But I have considered it as an >>>> option.)&#4294967295; I really don't see it becoming much more common, and outside >>>> of niche areas (defence, aerospace) it is very rare.&#4294967295; Programming in >>>> Ada >>>> often takes a lot more effort even for simple things, leading >>>> quickly to >>>> code that is so wordy that it is unclear what is going on. >>> >>> >>> That depends, I guess, on what one considers "simple", and also, of >>> course, on how familiar one is with the languages. >>> >>> Perhaps it is time to link once again to the experience of C versus Ada >>> in an introductory embedded-programming class using a model rail-road >>> example, where the students using Ada fared much better than those >>> using C: >>> >>> http://archive.adaic.com/projects/atwork/trains.html >> >> Are there no newer examples? > > > I have none to hand, at least. > > >> While this study was interesting, it is some 30 years out of date > > I would call it "30 years old". Whether it is "out of date" can be > debated -- I don't think the basic ideas of the two languages have > changed very drastically even in that time. >
C made a big leap, IMHO, with C99 - it became a significantly better language, and it became easier to write safe, clear and efficient code than with C90. (C11 and C17 add little in comparison.) C++ is a completely different language now than it was 30 years ago. And the tools for both C and C++ have changed hugely in that time. But some programmers have not changed, and the way they write C code has not changed. Again, it's a question of whether you are comparing how languages /could/ be used at their best, or how some people use them at their worst, or guessing something in between.
> >> and compares and old version of Ada with an old version of C (perhaps >> not even C90).&#4294967295; I'd rather see the pros and cons of Ada 2012 compared >> to C++17. > > So would I, but I haven't seen any such studies reported. > > I can only point to the biased material at > https://www.adaic.org/advantages/.
As an example of the bias, I looked at the "What constructs exist in Ada that do not have an equivalent construct in C/C++?" page. First off, anyone who talks about "C/C++" as though it were a single language is either ignorant or biased. Some of their points are outdated (C++ has "proper" array types in the standard library), and support for very nice syntaxes for literals). Some are fair enough - strong type checking of arithmetic types needs a good deal more effort (such as shown in the "strong typedef" link from earlier). Some are absolutely a point to Ada, such as named parameters. And the page is missing the "What constructs exist in C++ that do not have an equivalent in Ada?" list :-)
> > And a recent Ada-adoption story from NVIDIA: > > https://www.adacore.com/webinars/securing-future-of-embedded-software > > but that is more about the AdaCore tools and the SPARK form of Ada than > about C-vs-Ada. > >>> >>> I am (as you guessed) an Ada fan, and find it a pleasure to write, even >>> if it takes more keystrokes than the equivalent in C. >> >> I had no need to guess - it's not the first time you have posted about >> Ada here!&#4294967295; I'm glad that someone with your Ada qualifications can chime >> in here, and can correct my if I'm wrong. >> >>> >>> For embedded systems in particular, I find portability to be a great >>> advantage of Ada. With few exceptions, the embedded program can be >>> exercised on the development host, and if the target supports the >>> standard Ada tasking system (or a subset of it), this applies even to >>> multi-threaded programs (without the need to emulate some embedded >>> RTK/OS on the host). >>> >> >> For suitable targets, I can see that being useful.&#4294967295; C and C++ can be >> used on a wider range of targets, and with a wider range of RTOS (if >> any). > > > Ada can be used with other RTOSses too, although one loses both some > ease-of-use advantages and the portability advantage. Typical Ada > compilers for embedded systems also let one write Ada programs that do > not need an RTOS at all and run with a single thread. > > >> Of course, code for widely differing target systems is often very >> different anyway, so portability is not always a concern. >> >>> >>>> And most of the advantages of Ada (such as better typing) can be >>>> achieved in C++ with less effort, >>> >>> According to the link above, the main Ada advantage was the ability to >>> define one's own problem-oriented scalar types, such as integers with >>> specific value ranges. AIUI, this is not easily done in C++. >>> >> >> Sure it can be done in C++. >> >> <https://foonathan.net/2016/10/strong-typedefs/> > > I did not see any mention of range-checked types there. But yes, they > can be constructed in C++, but not as easily as in Ada, as it seems we > agree. I should have said "/as/ easily" in the quote above.
Once you have made appropriate templates, they can be used as easily as in Ada. But such templates are not in the C++ standard library.
> > >> You can make types with specific ranges (with compile-time checks where >> possible, optional run-time checks otherwise).&#4294967295; You can choose which >> operations you allow on them, and how they combine (so that multiplying >> a speed and a time give you a distance automatically, but adding them is >> not allowed).&#4294967295; You can make integer types with different overflow >> behaviour (wrapping, saturating, throwing errors, unspecified behaviour, >> undefined behaviour) that can be used as easily as normal integers, and >> mixed if and only if it is safe to do so or you make it explicit.&#4294967295; You >> can make array types that are indexed by enumerated types.&#4294967295; It's all >> possible - more so that in Ada, AFAIK. > > > I admit that C++ templates allow the programming of more compile-time > activities than Ada allows. >
C++ has got a lot stronger at compile-time work in recent versions. Not only have templates got more powerful, but we've got "concepts" (named sets of features or requirements for types), constexpr functions (that can be evaluated at compile time or runtime), consteval functions (that must be evaluated at compile time), constinit data (that must have compile-time constant initialisers), etc. And constants determined at compile-time are not restricted to scaler or simple types.
> >> Where you have a difference, however, is that many of the most >> beneficial cases (such as strong subrange types) are simple to use in >> Ada and built into the language, and therefore they are often used.&#4294967295; In >> C++, you need to find a suitable template library or make things >> yourself, giving a much higher barrier to use. > > > Yup. > > >> A very interesting distinction when looking at language features and >> safe coding is how much people /could/ use safety features, and how much >> they /do/ use them.&#4294967295; For example, with C programming you can get strong >> type safety as long as you wrap all your new types in structs.&#4294967295; The >> compiler will complain for type mistakes, just as it would in Ada - but >> the /use/ of such types is often very inconvenient in C. > > > Indeed. > > >>>> and at the same time C++ can give additional safety on >>>> resources that is harder to get on Ada.&#4294967295; (But Ada has some nice >>>> features >>>> introspective that C++ programmers currently only dream about.) >>> >>> >>> Can you be more specific on those points, please? >>> >> >> For the first point - my understanding is that in Ada, when you have >> classes you need to manually call constructor and destructor >> (initializer and finalizer) functions.&#4294967295; RAII is thus harder, and it is >> as easy to make mistakes as it is in C (with malloc and free).&#4294967295; Does Ada >> have the equivalent of std::unique_ptr, std::shared_ptr and other smart >> pointers, or container classes that handle allocation? > > > Answered in another message. The Ada "controlled" types have > automatically called initializer and finalizer operations. They can be > used to implement smart pointers, but no smart pointers are built into > Ada (perhaps mainly because they would then have to be thread-safe, > which would be a lot of overhead for a single-threaded program). > > >> For the second point, I am thinking of things like type attributes.&#4294967295; I >> would /really/ like C++ enumerations to have something matching the >> "first" and "last" attributes!&#4294967295; AFAIK, C++ won't get this until >> reflection is added, probably not until C++26. > > > Yes, good point in favour of Ada. I've seen some C++ programs that go to > great metaprogramming lengths to define "trait" templates to get the > equivalent of the "first", "last", "size" etc. attributes. So it is, > again, possible in C++, but not as easy as when it is built-in, as in Ada. >
Agreed. There is a proposal in the works for "metaclasses" in C++, which goes beyond reflection and into code generation. I'm looking forward to that - it will put an end to a lot of "boilerplate" code. But it's going to take a good while to arrive.
> >>>> It used to be the case that C++ compilers were expensive and poor >>>> quality, that the resulting code was very slow on common >>>> microcontrollers, and that the language didn't have much extra to offer >>>> small-systems embedded developers.&#4294967295; That, I think, has changed in all >>>> aspects.&#4294967295; I use gcc 10 with C++17 on Cortex-M devices, and features >>>> like >>>> templates, strong enumerations, std::array, and controlled automatic >>>> conversions make it easier to write good code. >>> >>> >>> AdaCore provides the gcc-based GNAT Ada compiler for several embedded >>> targets, free to use for open-source projects: libre.adacore.com. >>> >>> Commercial projects can use Ada on other targets by means of the >>> (different) AdaCore compiler that generates C code as an intermediate >>> representation. >>> >> >> This means that Ada suffers from a similar barrier to adoption that C++ >> used to do.&#4294967295; Big companies will happily pay the cost for the tools that >> they think will lead to better development efficiency or reliability. >> Smaller ones will have a much harder time trying to justify the expense, >> especially as they will often have few developers who can use the tools. >> A move from C to Ada is compounded by needing a complete change of the >> code - with C to C++, you can re-use old code, and you can also use a >> few of the C++ features rather than moving wholescale (though of course >> you also miss out on corresponding benefits). > > > Of course you can move from C to Ada without a full re-write, because > all Ada compilers provide inter-linking with C code, and most data > structures can be mapped between the two languages. (For some Ada > compilers like GNAT, this even holds for C++ and Ada) > > In fact, there is another C-vs-Ada study, > > http://archive.adaic.com/intro/ada-vs-c/cada_art.html > > where an Ada compiler vendor incrementally moved their Ada compiler from > being written in C to being written in Ada, and found a steady increase > of quality and decrease of cost-to-repair as modules were moved from C > to Ada. But it is from 1995, so perhaps "out of date" :-) >
You can move file by file from C to Ada, but you can move from C to C++ by adding the "-x c++" flag to your build or clicking the "compile C code as C++" on the IDE. Then you change as much or as little as you want, when you want.
On 18/04/21 18:26, David Brown wrote:
> But some programmers have not changed, and the way they write C code has > not changed. Again, it's a question of whether you are comparing how > languages/could/ be used at their best, or how some people use them at > their worst, or guessing something in between.
That is indeed a useful first question. A second question is "how easy is it to get intelligent but inexperienced programmers to avoid the worst features and use the languages well?" (We'll ignore all the programmers that shouldn't be given a keyboard :) ) A third is "will that happen in company X's environment when they are extending code written by people that left 5 years ago?"
On 18/04/21 18:26, David Brown wrote:
> C++ has got a lot stronger at compile-time work in recent versions. Not > only have templates got more powerful, but we've got "concepts" (named > sets of features or requirements for types), constexpr functions (that > can be evaluated at compile time or runtime), consteval functions (that > must be evaluated at compile time), constinit data (that must have > compile-time constant initialisers), etc. And constants determined at > compile-time are not restricted to scaler or simple types.
Sounds wordy ;)
On 18/04/2021 20:30, Tom Gardner wrote:
> On 18/04/21 18:26, David Brown wrote: >> C++ has got a lot stronger at compile-time work in recent versions.&#4294967295; Not >> only have templates got more powerful, but we've got "concepts" (named >> sets of features or requirements for types), constexpr functions (that >> can be evaluated at compile time or runtime), consteval functions (that >> must be evaluated at compile time), constinit data (that must have >> compile-time constant initialisers), etc.&#4294967295; And constants determined at >> compile-time are not restricted to scaler or simple types. > > Sounds wordy ;)
Have you looked at the C++ standards documents? There are more than a few words there! I'm not suggesting C++ is a perfect language - not by a long way. It has plenty of ugliness, and in this thread we've covered several points where Ada can do something neater and clearer than you can do it in C++. But it's a good thing that it has more ways for handling things at compile time. In many of my C projects, I have had Python code for pre-processing, for computing tables, and that kind of thing. With modern C++, these are no longer needed. An odd thing about the compile-time calculation features of C++ is that they came about partly by accident, or unforeseen side-effects. Someone discovered that templates with integer parameters could be used to do quite a lot of compile-time calculations. The code was /really/ ugly, slow to compile, limited in scope. But people were finding use for it. So the motivation for "constexpr" was that programmers were already doing compile-time calculations, and so it was best to let them do it in a nicer way.
On 18/04/2021 20:29, Tom Gardner wrote:
> On 18/04/21 18:26, David Brown wrote: >> But some programmers have not changed, and the way they write C code has >> not changed.&#4294967295; Again, it's a question of whether you are comparing how >> languages/could/&#4294967295; be used at their best, or how some people use them at >> their worst, or guessing something in between. > > That is indeed a useful first question. > > A second question is "how easy is it to get intelligent > but inexperienced programmers to avoid the worst features > and use the languages well?" (We'll ignore all the programmers > that shouldn't be given a keyboard :) ) > > A third is "will that happen in company X's environment when > they are extending code written by people that left 5 years > ago?"
All good questions. Another is what will happen to the company when the one person that understood the language at all, leaves? With C++, you can hire another qualified and experienced C++ programmer. (Okay, so you might have to beat them over the head with an 8051 emulator until they stop using std::vector and realise you don't want UCS2 encoding for your 2x20 character display, but they'll learn that soon enough.) With Ada, or Forth, or any other minor language, you are scuppered. These are important considerations.
On 18/04/21 21:23, David Brown wrote:
> On 18/04/2021 20:29, Tom Gardner wrote: >> On 18/04/21 18:26, David Brown wrote: >>> But some programmers have not changed, and the way they write C code has >>> not changed.&#4294967295; Again, it's a question of whether you are comparing how >>> languages/could/&#4294967295; be used at their best, or how some people use them at >>> their worst, or guessing something in between. >> >> That is indeed a useful first question. >> >> A second question is "how easy is it to get intelligent >> but inexperienced programmers to avoid the worst features >> and use the languages well?" (We'll ignore all the programmers >> that shouldn't be given a keyboard :) ) >> >> A third is "will that happen in company X's environment when >> they are extending code written by people that left 5 years >> ago?" > > All good questions. > > Another is what will happen to the company when the one person that > understood the language at all, leaves? With C++, you can hire another > qualified and experienced C++ programmer. (Okay, so you might have to > beat them over the head with an 8051 emulator until they stop using > std::vector and realise you don't want UCS2 encoding for your 2x20 > character display, but they'll learn that soon enough.) With Ada, or > Forth, or any other minor language, you are scuppered. > > These are important considerations.
They are important considerations, indeed. I'm unconvinced that it is practical to rely on hiring another C++ programmer that is /actually/ qualified and experienced - and wants to work on someone else's code. The "uncanny valley" is a major problem for any new tech, languages included. We've all seen the next better mousetrap that turns out to merely have exchanged swings and roundabouts.

The 2024 Embedded Online Conference