"Ravenscar-like" profile for C/C++

M

Marc Le Roy

Hello,

ADA Ravenscar is a restricted subset of the ADA language that has been
defined for real-time software development in safety critical applications.
Completed with additional restrictions like the ones defined in the SPARK
profile, it allow to build very deterministic applications that support
automatic static code analysis and schedulability analysis.
http://www.acm.org/pubs/articles/proceedings/ada/289524/p1-dobbing/p1-dobbing.pdf

I would like to know if there is a similar standard for C / C++. I found
only MISRA-C and EC++, but they are rather permissive with respect to the
Ravenscar ADA profile. Moreover, because the ADA standard covers concepts
that are out of the scope of the C/C++ standards, I suppose that an
equivalent of the Ravenscar profile in C/C++ should make reference to an
RTOS.

Marc

--
 
I

Ioannis Vranos

Marc Le Roy said:
Hello,

ADA Ravenscar is a restricted subset of the ADA language that has been
defined for real-time software development in safety critical applications.
Completed with additional restrictions like the ones defined in the SPARK
profile, it allow to build very deterministic applications that support
automatic static code analysis and schedulability analysis.
http://www.acm.org/pubs/articles/proceedings/ada/289524/p1-dobbing/p1-dobbing.pdf

I would like to know if there is a similar standard for C / C++. I found
only MISRA-C and EC++, but they are rather permissive with respect to the
Ravenscar ADA profile. Moreover, because the ADA standard covers concepts
that are out of the scope of the C/C++ standards, I suppose that an
equivalent of the Ravenscar profile in C/C++ should make reference to an
RTOS.


There is no reason for such a subset in C++. Use the part of C++ that fits
your needs. The whole language is designed for maximum run-time/space
efficiency. I place here the contents of a page of my old web site which i
think you will find useful:


--------------------------------------------------------

FAQ for common myths



Here ANSI/ISO C++ 1998 is discussed.



C++ is a general purpose programming language with a bias towards systems
programming. It is suitable for writing mission critical applications under
severe time and space constraints, like Operating Systems, real-time
simulations, etc. It is suitable for writing applications towards all kinds
of systems, from small embedded devices to large mainframes.

C++ is the dominant general purpose programming language. Other programming
languages like Visual Basic, C#, Java, etc are far behind in worldwide
adoption (a fact that many may not know due to commercial fads). In this FAQ
I shall be trying to debunk various C++ myths that are widespread and come
to my attention.



Myth 1

"C-style operations with low level stuff (built in arrays, etc) are faster
than high level C++ operations with containers and algorithms of the
standard library (templates, etc)".

Answer: This is a myth. Template and other constructs of the C++ standard
library are written in such a way so as to be as fast as possible and as
small as possible so as to be inlined. That means we usually have better
performance than our low level code, which is separated in functions and is
called with the cost of time that function calls have.



An example. Consider the code:

#include <ctime>
#include <cstdlib>
#include <cstring>
#include <vector>
#include <valarray>
#include <algorithm>
#include <iostream>


// For qsort()
inline int cmp(const void *p1, const void *p2)
{
return *static_cast<const int *>(p1)-*static_cast<const int *>(p2);
}


int main()
{
using namespace std;

const unsigned long SIZE=20*1024*1024;

int *p1=new int[SIZE];

srand(time(0));

// Random numbers created in the array on the free store
for(unsigned long i=0; i<SIZE; i++)
p1=rand();

int *p2=new int[SIZE];

memcpy(p2, p1, SIZE*sizeof(*p1));


// The numbers are copied from p to a vector<int>
vector<int>vecarray(p1, &p1[SIZE]);

// The numbers are also copied to a valarray<int>.
// valarray is an array container optimised for numerical computations.
valarray<int>vlarray(p1, SIZE);


clock_t t1, t2, t3, t4, t5, t6, t7, t8, temp;

// Wait to begin from a clear tick for accurate results
for(temp=t1=clock(); !(t1-temp); t1=clock())
;

sort(vecarray.begin(), vecarray.end());

t2=clock();

// Wait to begin from a clear tick for accurate results
for(temp=t3=clock(); !(t3-temp); t3=clock())
;

qsort(p1, SIZE, sizeof(*p1), cmp);

t4=clock();


// Wait to begin from a clear tick for accurate results
for(temp=t5=clock(); !(t5-temp); t5=clock())
;

sort(p2, p2+SIZE);


t6=clock();


// Wait to begin from a clear tick for accurate results
for(temp=t7=clock(); !(t7-temp); t7=clock())
;

sort(&vlarray[0], &vlarray[0]+vlarray.size());


t8=clock();

delete[] p1;
delete[] p2;

cout<<"\nvector<int>/sort() sorting time: "<<t2-t1<<" translated in
seconds: ";
cout<<static_cast<double>(t2-t1)/CLOCKS_PER_SEC<<endl;

cout<<"\nvalarray<int>/sort() sorting time: "<<t8-t7<<" translated in
seconds: ";
cout<<static_cast<double>(t8-t7)/CLOCKS_PER_SEC<<endl;

cout<<"\nint */qsort() sorting time: "<<t4-t3<<" translated in seconds:
";
cout<<static_cast<double>(t4-t3)/CLOCKS_PER_SEC<<endl;

cout<<"\nint */sort() sorting time: "<<t6-t5<<" translated in seconds:
";
cout<<static_cast<double>(t6-t5)/CLOCKS_PER_SEC<<endl;

}

This code creates a low level int array on the free store containing
"random" values, a second one with the same values, a C++ high level
vector<int> container and a C++ high level valarray<int> container with the
same contents. Then it measures the time each one needs to be sorted. At
the first C-style array the C subset qsort() is applied. At the second
C-style array the C++ high level sort() (template) is applied. For the C++
high level vector<int> and valarray<int> (templates), the C++ high level
sort() (template) is applied. At the end the program outputs the timings.



The results on a PIII 1000 MHz, 1024 MB RAM:

MINGW GCC version 3.1 (Windows port) :

g++ temp.cpp -o
temp -pedantic-errors -Wall -fexpensive-optimizations -O3 -ffloat-store -mcp
u=pentiumpro

C:\c>temp

vector<int>/sort() sorting time: 10345 translated in seconds: 10.345

valarray<int>/sort() sorting time: 8051 translated in seconds: 8.051

int */qsort() sorting time: 14050 translated in seconds: 14.05

int */sort() sorting time: 8342 translated in seconds: 8.342



Borland C++ 5.5:

bcc32 -O2 -6 temp.cpp

C:\c>temp

vector<int>/sort() sorting time: 14561 translated in seconds: 14.561

valarray<int>/sort() sorting time: 14140 translated in seconds: 14.14

int */qsort() sorting time: 15963 translated in seconds: 15.963

int */sort() sorting time: 14311 translated in seconds: 14.311



Intel C++ 6:

icl /EHa /G6 /O3 /Qansi /Za /Qipo temp.cpp

C:\c>temp

vector<int>/sort() sorting time: 10094 translated in seconds: 10.094

valarray<int>/sort() sorting time: 8743 translated in seconds: 8.743

int */qsort() sorting time: 12929 translated in seconds: 12.929

int */sort() sorting time: 9053 translated in seconds: 9.053



Visual C++ 2002 .NET:

cl /EHa /Ox /G6 /Za /Wp64 temp.cpp

C:\c>temp

vector<int>/sort() sorting time: 8522 translated in seconds: 8.522

valarray<int>/sort() sorting time: 8352 translated in seconds: 8.352

int */qsort() sorting time: 13209 translated in seconds: 13.209

int */sort() sorting time: 8392 translated in seconds: 8.392



So by using C++ higher level constructs we maintain at least the efficiency
of C low level equivalents while enjoying the high level comfort and safety
C++ provides. And in many cases we even gain in time/space efficiency.



References: http://www.research.att.com/~bs/esc99.html

http://www23.brinkster.com/noicys/docs/ms-speaking-cpp.pdf 215 KB PDF file



[Last updated: 27 February 2003]

Copyright © 2001-2003 Ioannis Vranos
-------------------------------------------






Regards,

Ioannis Vranos
 
M

Marc Le Roy

Ioannis said:
There is no reason for such a subset in C++. Use the part of C++ that
fits your needs.

It seems that you don't know very well the world of high integrity systems,
especially the ones that require certification according to standards like
DO178B level A ;-)

You should have a look to this document:
http://polaris.dit.upm.es/~str/proyectos/ork/documents/RP_ug.pdf
especially to section 2, that explain why such a restrictive ADA profile has
been defined.

It is true that the problems in relation with tasking do not exist in C++
because tasking is not part of the C++ standard, but other remains. In fact,
having a good experience of using both C and C++ in real time projects [yes,
they are different languages ;-) ], I have a good idea of what can or cannot
be used in safety critical systems. But I am pretty sure that both my
customer and certification authorities will have a greater confidence in a
established standard than in my opinion :)

Marc
 
J

Jack Klein

There is no reason for such a subset in C++. Use the part of C++ that fits
your needs. The whole language is designed for maximum run-time/space
efficiency. I place here the contents of a page of my old web site which i
think you will find useful:

[large snip]

You have completely mis-understood the question.

The issues here have nothing at all to do with run-time/space
efficiency, but about, as the OP specifically stated, "safety critical
applications". The phrase you used in the part of your overly long
pedantic message that I snipped, "mission critical applications", is
not, never has been, and never will be remotely similar. In fact, it
is nothing more than a marketing buzz word.

This renders your answer meaningless in the context.
 
J

Jack Klein

It seems that you don't know very well the world of high integrity systems,
especially the ones that require certification according to standards like
DO178B level A ;-)

It is true that Ioannis completely misunderstood the question.
You should have a look to this document:
http://polaris.dit.upm.es/~str/proyectos/ork/documents/RP_ug.pdf
especially to section 2, that explain why such a restrictive ADA profile has
been defined.

You should understand that anything in that document is irrelevant in
comp.lang.c++, and your question just as off-topic here as it was in
comp.lang.c.

Even if there were a similar document for C and/or C++, it would be
off-topic in comp.lang.c and comp.lang.c++.
It is true that the problems in relation with tasking do not exist in C++
because tasking is not part of the C++ standard, but other remains. In fact,
having a good experience of using both C and C++ in real time projects [yes,
they are different languages ;-) ], I have a good idea of what can or cannot
be used in safety critical systems. But I am pretty sure that both my
customer and certification authorities will have a greater confidence in a
established standard than in my opinion :)

Marc

Whatever "established standards" there might or might not be, they
would be off-topic in both comp.lang.c and comp.lang.c++, unless they
were part of ISO 9899 and/or ISO 14882.

This discussion, as I already pointed out, belongs in groups like
and Language
subsetting, for whatever purpose, is not defined by the ISO standard
for either C or C++, and is not topical here. Nor is safety critical
programming.
 
I

Ioannis Vranos

Jack Klein said:
The phrase you used in the part of your overly long
pedantic message that I snipped, "mission critical applications", is
not, never has been, and never will be remotely similar. In fact, it
is nothing more than a marketing buzz word.


Why marketing buzz word? You can do something like:


#include <fstream>
#include <string>
#include <cctype>


class DictionaryFileException
{
};


class dictionaryFile
{
std::ifstream dicFile;
std::string dicFileName;

public:
dictionaryFile(const std::string &filePath) throw (DictionaryFileException)
{
dicFileName=filePath;
dicFile.open(filePath.c_str());

if(dicFile.fail())
throw DictionaryFileException();

FileValidation();
}

void FileValidation() throw (DictionaryFileException)
{
using namespace std;

char input[256];

do
{
dicFile.get(input,256);

if(isspace(input[0]) or (input[0]=='\\' and input[1]=='\\'))
continue;

else if(!isalpha(input[0]) and !isdigit(input[0]))
throw DictionaryFileException();

}while(!dicFile.eof());
}
};



C++ provides the necessary structures to built very reliable, efficient and
mission critical systems. In the above i define what exceptions are expected
from each member function, and we can also use the Resrource Aquisition is
Initializatization technique which the standard library itself also uses.






Ioannis Vranos
 
M

Martin Krischik

Finallylein wrote:

This discussion, as I already pointed out, belongs in groups like
and Language
subsetting, for whatever purpose, is not defined by the ISO standard
for either C or C++, and is not topical here.
Nor is safety critical programming.

Finaly a C / C++ programmer who confesses that safety critical programming
is in deed off topic in C and C++.

Grin

Martin
 
M

Martin Krischik

Ioannis said:
C++ provides the necessary structures to built very reliable, efficient
and mission critical systems. In the above i define what exceptions are
expected from each member function, and we can also use the Resrource
Aquisition is Initializatization technique which the standard library
itself also uses.

The problem with savety critical programming in C or C++ is not what is
allowed or possible but what should not be allowed and should be
impossible. And for that I just need two line:

char X[10];
X[10]='A';

With Regards

Martin
 
I

Ioannis Vranos

Martin Krischik said:
Ioannis said:
C++ provides the necessary structures to built very reliable, efficient
and mission critical systems. In the above i define what exceptions are
expected from each member function, and we can also use the Resrource
Aquisition is Initializatization technique which the standard library
itself also uses.

The problem with savety critical programming in C or C++ is not what is
allowed or possible but what should not be allowed and should be
impossible. And for that I just need two line:

char X[10];
X[10]='A';


From TC++PL3:


"Indexing is done by operator[]() and at(); operator[]() provides unchecked
access, whereas at() does a range check and throws out_of_range if an index
is out of range. For example:

void f(vector<int>& v, int i1, int i2)
try {
for(int i = 0; i < v.size() ; i++) {
// range already checked: use unchecked v here
}


v.at(i1) = v.at(i2) ; // check range on access
// ...
}

catch(out_ of_ range) {
// oops: out-of-range error
}

This illustrates one idea for use. That is, if the range has already been
checked, the unchecked subscripting operator can be used safely; otherwise,
it is wise to use the range-checked at() function. This distinction is
important when efficiency is at a premium."






Ioannis Vranos
 
M

Michiel Salters

Martin Krischik said:
Ioannis Vranos wrote:

The problem with savety critical programming in C or C++ is not what is
allowed or possible but what should not be allowed and should be
impossible. And for that I just need two line:

char X[10];
X[10]='A';

What's the problem with that code, from a safety perspective? Certainly
a C compiler which is supposed to be suited for safety-critical programs
will diagnose this. The base C and C++ languages have quite a number
of "undefined behavior - no diagnostic required" cases, but a similar
profile may very well tighten that to "undefined behavior - must be
rejected at compile time".

The base philosophy in C and C++ is that flexibility can be traded
for safety, but not vice versa. Certainly, in C++ it is easy to
create a verifiable subset. For instance, it is possible to define
a range template and with it a <int,0,10> type. The toolset would
be hard pressed to prove that the range template is correct and
overflow-free. However, this could be proven by humans. The tool
chain instead only has to check that all possible overflows are
located in this checked range< > code. Together, this would prove
that a body of code is overflow-free.

Regards,
Michiel Salters
 
V

Vinzent 'Gadget' Hoefler

Michiel said:
Certainly, in C++ it is easy to
create a verifiable subset.

Not quite true. Or maybe the FIASCO project just did not find it yet?


Vinzent.
 
M

Marc

Hello Jack,

Sorry for this late answer, but I received none of your messages in my
normal newsfeed.

Jack Klein said:
You should understand that anything in that document is irrelevant in
comp.lang.c++, and your question just as off-topic here as it was in
comp.lang.c.

Even if there were a similar document for C and/or C++, it would be
off-topic in comp.lang.c and comp.lang.c++.

I don't agree : this forum seems very suitable for discussions
concerning which part of the C++ standard can be used to get some
properties in applications and which part cannot be used. It is true
that some objectives that are enumerated in section 2 of the document
I mentionned concern tasking, which is not part of the C++ standard.
But for example, the objectives listed in section 2.4 are relevant for
C++.

Marc Le Roy
 
C

Craig Carey

Ioannis Vranos wrote: ....
You should have a look to this document:
http://polaris.dit.upm.es/~str/proyectos/ork/documents/RP_ug.pdf
especially to section 2, that explain why such a restrictive [Ada] profile has
been defined.

You should understand that anything in that document is irrelevant in
comp.lang.c++, and your question just as off-topic here as it was in
comp.lang.c.

Even if there were a similar document for C and/or C++, it would be
off-topic in comp.lang.c and comp.lang.c++.

I was mentioing how Ada 95 is apparently better designed than Zonnon; at
comp.lang.oberon.
Zonnon ( http://zonnon.ethz.ch/ ) is an advancement on Oberon, but it
has limitations in the multitasking area.

There seems to be no correct "relevance principle that can be buttoned
onto every Usenet group on programming languages.

Thanks

....
 
M

Michiel Salters

Vinzent 'Gadget' Hoefler said:
Not quite true. Or maybe the FIASCO project just did not find it yet?

Quite true. For instance, if i restrict C++ to the subset which allows
only

int main() { }

I know that that subset is perfectly verifiable. For instance,

int main() { int i; }

is not in the subset. This shows the main problem: Safe and verifiable
subsets are more easiliy created by building from the bottom, not
stripping from the top. Yet powerful subsets are created by removal
of a few features from the full language.

However, it doesn't have a lot to do with the FIASCO project. The goal
there was to deal with a lof of known unsafe features. Some were even
unsafe by design (e.g. reinterpret_cast<>). This is not an issue when
creating safe subsets; reinterpret_cast<> is the first feature to go.

FIASCO is also hindered by a lack of understanding of C++:
One of the few things that are required is that all built-in integer
types are at least 7 bits wide.
Now, as range errors in vaiables are a common cause of errors, this is
a rather painful lack of understanding.
 
V

Vinzent 'Gadget' Hoefler

Michiel said:
Quite true. For instance, if i restrict C++ to the subset which allows
only

int main() { }

I know that that subset is perfectly verifiable.

Ok. Perhaps we should add "sufficiently usable", too. :)
is not in the subset. This shows the main problem: Safe and verifiable
subsets are more easiliy created by building from the bottom, not
stripping from the top. Yet powerful subsets are created by removal
of a few features from the full language.

Well, I'd say that SPARK as an verifiable Ada-subset is quite
successful in that regard. I doubt that an equally verifiable subset
of C++ can ever be implemented. But perhaps that's just me.
FIASCO is also hindered by a lack of understanding of C++:
One of the few things that are required is that all built-in integer
types are at least 7 bits wide.
Now, as range errors in vaiables are a common cause of errors, this is
a rather painful lack of understanding.

I don't exactly understand. Just because they _require_ all their
built-in integer types to have at least 7 bit, they don't understand
C++? I don't see the relevance here.

And if we really talk about _verifiable_, the actual implementation
doesn't matter that much (you just need to know about it), because you
should be able to _prove_ that no kind of overflow can occur under any
circumstances. Well, given that the hardware does what it is supposed
to do, of course.


Vinzent.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,774
Messages
2,569,596
Members
45,143
Latest member
SterlingLa
Top