[DISCUSSION] Rationale for yet another C variant

A place of insane ideas, nothing to see here.
User avatar
DeusExMachina
Posts: 219
Joined: Tue Apr 03, 2012 5:08 am
Location: South Korea
Has thanked: 3 times
Been thanked: 3 times

Re: [DISCUSSION] Rationale for yet another C variant

Postby DeusExMachina » Wed Jan 03, 2018 2:49 am

I think the industry already has a solution to these woes :) How about ADA? It is widely used in the US military projects and there is a free GNAT compiler for experiments.

User avatar
Giovanni
Site Admin
Posts: 11083
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 367 times
Been thanked: 306 times
Contact:

Re: [DISCUSSION] Rationale for yet another C variant

Postby Giovanni » Wed Jan 03, 2018 9:15 am

Hi,

ADA has been there for a while and has not been widely adopted, it would be interesting understand why.

I think that by design it sits on an OS with a rather complex runtime. My idea for an embedded language is that it should not depend on any runtime or library. This is one of the best qualities of C too, you can ignore its library and use it like an high level assembler.

Rather that putting "tasks" in the language (this would require an underlying support for tasking) the language should provide mechanism for tracking access dependencies on the shared data. No built-in concept of ISRs/tasks/threads/processes/other. You are using the language to implement those things, not just using them.

Most languages try to abstract complex things and, by doing this, fail to be a real replacement for C.

Anyway, I agree that ADA is the closest thing to an inherently safe language that allows for low level programming.

Giovanni

User avatar
DeusExMachina
Posts: 219
Joined: Tue Apr 03, 2012 5:08 am
Location: South Korea
Has thanked: 3 times
Been thanked: 3 times

Re: [DISCUSSION] Rationale for yet another C variant

Postby DeusExMachina » Thu Jan 04, 2018 2:16 am

AFAIK, the Ravenscar profile is very similar to your ideas, Giovanni.
https://en.wikipedia.org/wiki/Ravenscar_profile

The language itself supports many RTOS primitives
http://blog.adacore.com/theres-a-mini-r ... y-language

They say it can run on Cortex M0. There is an existing Ravanscar runtime for ARM Cortex Mx and HW drivers collection.

Here are some examples of ADA prjects
http://blog.adacore.com/tag/STM32

Personally I have never tried ADA for embedded, but you might be interested how ADA coincides with your ideas

User avatar
Giovanni
Site Admin
Posts: 11083
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 367 times
Been thanked: 306 times
Contact:

Re: [DISCUSSION] Rationale for yet another C variant

Postby Giovanni » Thu Jan 04, 2018 9:16 am

Hi,

It doesn't coincide much, it sits on a runtime, my idea is to have a primitive language that allows to safely write low level code without needing a runtime.

Other differences:
- Being based on C should ease adoption.
- The general idea is to make the language simpler, safer and closer to machine, not to add abstractions. ADA looks quite complex.
- There is no abstraction of tasks, ISRs or other mechanisms, only definition of "asynchronous functions" and ways to handle dependencies on shared data. The idea is to make anything touched by asynchronous functions accessible only through a common construct which could then implement critical sections, mutexes, monitors or other mechanisms but those mechanisms are not part of the language.

The peculiarity of C is that it sits at absolute bottom, there is no required runtime nor libraries, this is why I call it an "high level assembler". Safer C should retain this peculiarity.

Giovanni

apmorton
Posts: 29
Joined: Fri Sep 29, 2017 10:26 am
Been thanked: 13 times

Re: [DISCUSSION] Rationale for yet another C variant

Postby apmorton » Fri Jan 12, 2018 11:09 am

I agree with Korken, much of what you are wanting exists in C++.
Now, many of the things you want to explicitly _remove_ from the language do still exist in C++, but generally I think you will have a harder time building a language from scratch that would end up being largely incompatible with existing code bases and libraries than you would building on top of something like C++. You may not be able to entirely remove unsafe constructs from the language, but I honestly don't know if such a thing is possible in a meaningful way. At some point you will have to bend the safety rules for performance or to inter-operate with some external library that would be too costly to redevelop, and the language needs to have a way to do this. That could be through explicit marking of "unsafe" code, like how rust does it, or encapsulation techniques like are common in C++ - where an object type implements explicit cast operators that allow you to do the right thing _safely_ from _user code_, so long as you did the right thing when designing the types. But in either case, the language will be unable to prevent "sloppy" code from compiling if people want to compile sloppy code.

Largely, I think the direction that people have been moving is improvement of compile time analysis and tooling. clang-tidy is an amazing example of this. (http://clang.llvm.org/extra/clang-tidy/). it is a static analysis tool for C/C++ (mostly C++) that is highly extensible, and allows you to enforce complex constraints on a code base (and in cases where its semantically possible, automatically correct violations).

My final point - it is largely a misnomer that C++ is requires runtime libraries, or generates prohibitively large assemblies. C++ (the language) requires no special runtime, and will generate very small code when your compiler is configured to do so. If you stick to using zero overhead abstractions, avoid runtime type information, and ban the usage of exceptions, the generated code can often be the same or marginally smaller than equivalent C code due to much better optimizations in modern C++ compilers. Of course the STL (and many other) C++ libraries rely heavily on dynamic memory allocation - but so do many general purpose C libraries. There are alternatives. ETL (https://www.etlcpp.com/) is a good static allocation alternative to many STL features. It is also quite trivial to entirely disable dynamic memory allocation in C++ so you can be sure no code is sneaking it in behind your back (override the global new operator in a way that will throw a linker error - your code will still compile, but if anything references global new operator, a link error will occur).

User avatar
Giovanni
Site Admin
Posts: 11083
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 367 times
Been thanked: 306 times
Contact:

Re: [DISCUSSION] Rationale for yet another C variant

Postby Giovanni » Fri Jan 12, 2018 2:39 pm

Hi,

Having an "unsafe" code call is a good idea for reuse. Consider that the "normal" use case would be to create something using Safer C then use this thing, lets say for example an RTOS, from other languages, C/C++ or other.

I know C++ does not rely on huge runtime support, my criticism was directed to newer language arguing that cannot be a C replacement because that. Removing exceptions support and RTT is the first thing I do when using C++ in embedded.

About doing things on top of C++, different approach, my idea is to remove intrinsically unsafe features first then add what is necessary to enforce safety during development.

In addition, I am targeting only embedded/system development, not trying to create a general purpose language.

Giovanni

User avatar
Korken
Posts: 270
Joined: Wed Apr 02, 2014 4:09 pm
Location: Luleå, Sweden
Has thanked: 5 times
Been thanked: 6 times
Contact:

Re: [DISCUSSION] Rationale for yet another C variant

Postby Korken » Fri Jan 12, 2018 2:45 pm

If you want an intrinsically safer language and no not want to go with C++ or Rust, I would recommend to just make a high level language that decomposes into C++ / Rust to leverage the decades of ideas already implemented in the languages.

If you check the RTFM language I liked earlier, it is simply a translator for the "RTFM-core" language to C.
You can check the implementations of the parser and lexer that are written in OCaml there, which allowed us to do formal verification that the "compiler" was correct. We tested a lot, but a functional language made it really fast to develop in.

User avatar
Giovanni
Site Admin
Posts: 11083
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 367 times
Been thanked: 306 times
Contact:

Re: [DISCUSSION] Rationale for yet another C variant

Postby Giovanni » Fri Jan 12, 2018 2:51 pm

No doubts.

A translator from "Safer C" to plain C is one of the things I am considering. Probably easier than writing a new GCC frontend.

Giovanni

User avatar
HDKLog
Posts: 31
Joined: Thu Aug 18, 2016 12:36 am
Been thanked: 1 time

Re: [DISCUSSION] Rationale for yet another C variant

Postby HDKLog » Sun Jan 28, 2018 3:59 am

Hello,
any kind of code analyser will increase building and compilation time, and they will not be able to check all possible conditions because C language gives you a lot of degrees of freedom which came with a cost of stability. All high level languages just encapsulate checks and that is one of the reason, why they not used in embedded systems, where simplicity and code size comes in front. I think the best way of dealing with that problems is to make or use existing disciplines, which will prevent or at last make it easy to find out where problems can occur. For example code refactoring and unit tests come handy in this case.

Thargon
Posts: 71
Joined: Wed Feb 04, 2015 5:03 pm
Location: CITEC, Bielefeld University, germany
Has thanked: 4 times
Been thanked: 6 times

Re: [DISCUSSION] Rationale for yet another C variant

Postby Thargon » Tue Mar 06, 2018 6:30 pm

Hi,

after some experiments with C-only and C++-only projects I have actually decided to use some mix of both for embedded programming. And actually much of it was inspired by ChibiOS ;) I agree, that C++ can do all the things you are looking for, Giovanni, but I also agree, that C++ code tends to become inefficient and unsafe. This becomes very obvious when students with no experience in embedded programming start to use our system. However, my opinions about these two languages are:

C
  • + very clean, straight forward code
  • + very explicit (no surprises in the background)
  • + great to maintain
  • + easy to add features
  • + almost everyone knows C
  • + very portable (many other languages and tools feature C interfaces)
  • - either unsafe (e.g. cast to void*) or inefficient (e.g. type safe wrapper/converter functions)
  • - flaws in the standard (e.g. inline may or may not be inline)

C++
  • + object oriented
  • + abstraction with zero overhead
  • + type safe compile time stuff (templates, constexpr, etc.)
  • + almost everyone knows C++
  • - almost nobody knows how to use C++ for embedded
  • - many features unsuitable for embedded (e.g. vtables) without good alternatives (mostly fallback to C)
  • +/- most of the pros and cons of C

When talking about a new language, you should not only consider properties like safety and efficiency, but also usability - how fast can you get things done. I personally stick to clean C most of the time and I think unsafe code is acceptable as long as you know what you are doing. By enabling according compiler warnings, it is not even that risky anymore, as you are informed about implicit casts etc. For interfaces that are supposed to be used by others (who may not know what they are doing), I provide C++ classes and such. As a result, you get a fast, type safe framework, which can be used in a safe, comfortably, object oriented manner. Nevertheless, it would be great to have a language where you get both at the same time. Maybe something like "C with templates" could be close to what we are looking for. I have no experience with Rust, however, so there might be some useful features to incorporate from there as well.

When it comes to runtime safety, though, this is something that can not be solved by any language. You can analyse your code, of course, and optimize execution order or whatsoever, like Korken did in his work, but not on a language level (except maybe assembly?). If a developer wants to do messy things, a language can not stop him, and I think this is actually very important. If you want to try something new in some creative way, it would be counterproductive if the tool (the language) would prevent this. Only by allowing developers to do something wrong, they can actually do something better - something that was not considered when the language was designed.

My opinion
A language such as Giovanni proposed would of course be great to guarantee safe and efficient code, but it will never be able to handle runtime checks at compile time by itself. It will furthermore limit its capabilities to the use cases that were considered at the time of its definition.
While C and C++ are probably not optimal for embedded systems (I don't know about Rust), they are quite close and they are well known. So when it comes to "being better" and "getting things done", any new language will have a hard time to rival those.

Anyway, if safety and efficiency of the resulting system is the primary goal, you should probably think about throwing away your microcontroller/SoC and use an FPGA instead. You just need some time to get used to VHDL (or something similar), take some IP cores, glue them together, spice it up with your own logic, and you are as safe and efficient as you can get (except for ASICs).

so far...
Thomas

EDIT: I just remembered the D language (https://en.wikipedia.org/wiki/D_(programming_language)). I only did some tutorials. but one of its primary goals is to calculate as much as possible at compile time, something C++ encourages but not enforces.


Return to “Safer C”

Who is online

Users browsing this forum: No registered users and 1 guest