Teaching new tricks to an old dog (C++ -->Ada)

  • Thread starter Turamnvia Suouriviaskimatta
  • Start date
J

jayessay

Paul Mensonides said:
Neither do macros in C or C++. They operate on tokens. In any
case, the difference is meaningless.

Actually the difference is very important.

The only thing that matters is what the semantics are
Indeed.


(such as name binding). Lisp macros are easily inferior to Scheme
macros in that sense.

No, they are a proper superset of Scheme macros. The hygiene issue
is largely irrelevant due to CL being a lisp2 (while Scheme is a
lisp1).

That is exactly what they do.

No, but I don't think you will understand this anytime soon. Let me
ask you here, just _why_ do you think this? Maybe more to the point,
what do you think "parameterization" means here? It may be that we
are just not on the same page with the term definitions.

in the form of a syntax tree or not. The kind of thing that you
seem to be referring to is what Haskell does instead.

No, plain Haskell has no facility for this, but there are macro
systems that have been placed on it to provide some of the capability.

Obviously.

;-)


/Jon
 
P

Pascal Obry

Jean-Pierre Rosen said:
Actually, I think he borrowed it from my "pensees" web page (sorry, it is in
French) at http://www.adalog.fr/publicat/pensees.htm)

No I think I read that in your book about Ada (don't have the name handy).

Pascal.

--

--|------------------------------------------------------
--| Pascal Obry Team-Ada Member
--| 45, rue Gabriel Peri - 78114 Magny Les Hameaux FRANCE
--|------------------------------------------------------
--| http://www.obry.org
--| "The best way to travel is by means of imagination"
--|
--| gpg --keyserver wwwkeys.pgp.net --recv-key C1082595
 
C

Chad R. Meiners

Jerry said:
The point is that picking the language for that 70% seems to
take one choice in one list box -- i.e. the most utterly trivial amount
of work possible.

What are you trying to say with this sentence? It seems devoid of any
relavent information or meaning.
are you honestly suggesting that
it's particularly likely that they'd choose to generate C if they were
planning to write the remainder in Ada?

Now I don't have to be pigeon holed into only that suggestion. There
are more reasonable suggestions. For instance, they could be reusing
libraries written in Ada for maybe 10% of the remaining code. Another
15% could use this libraries and thus be written in Ada.
I don't recall anybody here having suggested that SCADE is the be-all
and end-all of format tools.

I never said you did. I was assuming that SCADE is a decent formal
tool which implies that they use SCADE to generate a most complete
subsystem that represented about 70% of the code base.
I drew exactly two conclusions: 1) that 100% minus 70% leaves 30%, and
2) that these _seem_ to be sufficiently large projects that 30% of them
still constitutes a substantial amount of code.

Exactly two huh? What about
It seems likely to me that if
they were using Ada for the hand-written code, they'd generate Ada
as well.

That looks like a conclusion to me. That sentence that you are
misquoting applies to all you conclusions and implicit implications.
Furthermore, if are calling
100% minus 70% leaves 30%

a conclusion as oppose to an assertion. One should expect that it was
preceeded by an arguement or proof of some sort. Being that you didn't
provide either, this "conclusion" is either a) actually an assertion
and disqualified to be member of your "exactly two conclusions" or b) a
conclusion that you jumped to by not providing an arguement to support
it.

And just for kicks
please expound on your form of math in which 100 minus 70 doesn't
equal 30.

when the numbers are in base 8 of course ;-)
 
C

Chad R. Meiners

Jerry said:
First of all, at least in my dictionary, "indicate" is defined with
words like "points to" and "suggests", NOT "proves" or anything very
similar.

Really?

http://dictionary.reference.com/search?q=indicates
entry four
"To state or express briefly (e.g. indicated his wishes in a letter;
indicating her approval with a nod.)"

seems to provide the most appropriate definition, which just happens to
support my statement. You should also note that the "points to" and
"suggests" entries have other very important words next to them which
render them as inappropriate to use for the meaning of the word
"indicate" in this dialog.
Second, I have to wonder whether you really have a good idea of the
size of project we're talking about.

Yes, I have a decent idea as to the size of the project. However, this
is irrelevent.
Second, unless porting Ada compilers is a LOT more expensive than
porting C++ compilers
<and so on>

I thought we were talking about C compilers. Anyway my point is that
is that if SCADE already generates C code and the subsystem that they
are targetting with SCADE has a C compiler. Why should they commision
an Ada compiler so that they could generate Ada code only to compile it
back to machine code when the C compiler will generate the machine
code? C (in the can of SCADE) is the intermediate language because it
has the available compilers for the targetted platform.
I'll openly admit that the slides don't absolutely _prove_ nearly as
much as we'd like to know.

Wow! I am impressed by the extent of you admission. We have made real
progress here in your admission of the trivial.
They're generally vague, lacking detail,
definition or rigor -- but despite that they still constitute roughly
95% of the hard evidence presented so far in this entire thread!

I submit this paperweight as hard evidence. I am not sure as to what
it is evidence of, but I know it is hard. That was demonstrates when I
dropped it on my foot ;-) So now this paperweight makes up 25% percent
of the evidence.

I am curious how these three presentations can make of 95% of
something. 75% I can see but 95%?
 
J

Jean-Pierre Rosen

Pascal Obry a écrit :
No I think I read that in your book about Ada (don't have the name handy).
Yes, it is in both... I just took the opportunity for a shameless plug :)
 
P

Peter Koch Larsen

Tapio Kelloniemi said:
The question is not only about compiler warnings or errors. Ada (as a
language) has been designed so that it is possible for the
compiler to check many mistakes which may cause bad results at run time.
Ada also makes it easier for the user to notice this kind of errors.
For example:

procedure X is

type Metres is new Natural;
type Seconds is new Natural;

M : Metrses := 0;
S : Seconds := 10;
begin
if M < S then -- Error, < is not defined for these types

But now you have problems calculating the velocity, right?

type Velocity is new Natural;
V: Velocity = M/S; // probably a compiler error.
...
end if;
end X;

This is a bit more verbose than using pure int instead of Metres and
Seconds, but if I wanted a C++ compiler to check this kind of error, I'm
afread that the resulting C++ code would be much more verbose.

Not so. There is an excellent library which does exactly what you want -
using templates, of course.
Such mistakes as using a pointer to nothing and writing past the array
bounds don't often happen in Ada.
What makes you believe they happen regularly in C++?
procedure Temp is
I : Integer := 0;
J : Natural := 4;
begin
I < J;
end Temp;

Without any warnings:
# gnatmake temp
gcc -c temp.adb
temp.adb:5:05: missing ":="
gnatmake: "temp.adb" compilation error

Notice how the language prevents doing useless things.

If a replace I < J; with null; the result is:
gcc -c -gnatg temp.adb
temp.adb:2:04: warning: "I" is not modified, could be declared constant
temp.adb:2:04: warning: variable "I" is not referenced
temp.adb:3:04: warning: "J" is not modified, could be declared constant
temp.adb:3:04: warning: variable "J" is not referenced
gnatmake: "temp.adb" compilation error

I see no real difference here between a good-quality C++ compiler and Ada.
/Peter
 
T

Tapio Kelloniemi

Peter Koch Larsen said:
But now you have problems calculating the velocity, right?

type Velocity is new Natural;
V: Velocity = M/S; // probably a compiler error.
Yes, but I can tell the compiler that I know better:
V : Velocity := Velocity (Integer (M) / Integer (S));

Also other readers of my code now know surely that this is what I meant.
Not so. There is an excellent library which does exactly what you want -
using templates, of course.

That is a good thing. If all C++ programmers used it, I think their
programs would benefit a lot of it.
What makes you believe they happen regularly in C++?

They just happen. Why people had otherwise created such tools as valgrind
(http://valgrind.kde.org/). I also use it myself for Ada to eliminate memory
leaks. Writing past array bounds unintentionally is quite easy. In Ada
Constraint_Error is raised, but C++ program segfaults. Or even worse, it
does not segfault immediately, but when the function is exited (as the
return address has been destroyed). STL is safer, but it cannot always be
used (eg. when interfacing to foreign code).
An example. First compile with the default behaviour, then with all
warnings tu
rned on:
[--]
If a replace I < J; with null; the result is:
gcc -c -gnatg temp.adb
temp.adb:2:04: warning: "I" is not modified, could be declared constant
temp.adb:2:04: warning: variable "I" is not referenced
temp.adb:3:04: warning: "J" is not modified, could be declared constant
temp.adb:3:04: warning: variable "J" is not referenced
gnatmake: "temp.adb" compilation error

I see no real difference here between a good-quality C++ compiler and Ada.

Another example:

int* f()
{
int i = 3;
int& l = *(new int);

l = i;
int* p = &i; // Should be int* p = &l;

return p;
}

int main()
{
int* p = f();
*p = 4;
return 0;
}

# g++ -Wall -o temp temp.cc
#

Not even a warning and the program does not crash on my system! Valgrind
revealed the error (and thought it was a G++ bug).
If the code above is modified a bit, even the best compiler cannot
know for sure that we are doing evil things.

The same in Ada:

procedure Temp is
type Int_Ptr is access Integer;

function F return Int_Ptr is
I : Integer := 3;
L : Int_Ptr := new Integer;
P : Int_Ptr;
begin
L.all := I;
P := I'Access; -- Should be P := L;
return P;
end F;

A : Int_Ptr;
begin
A := F;
A.all := 4;
end Temp;

# gcc -c -gnatg temp.adb
temp.adb:5:04: (style): subprogram body has no previous spec
temp.adb:11:12: prefix of "Access" attribute must be aliased

So if I really want to pass a pointer to a local to the caller, I should
change
I : Integer := 3;
to
I : aliased Integer := 3;

Also note that the lines which were "mistyped" are much closer to each
other in C++ than in Ada.
 
P

Pascal Obry

Tapio Kelloniemi said:
Yes, but I can tell the compiler that I know better:
V : Velocity := Velocity (Integer (M) / Integer (S));

or

function "/" (M : in Metres; S : in Seconds) return Velocity;

Pascal.

--

--|------------------------------------------------------
--| Pascal Obry Team-Ada Member
--| 45, rue Gabriel Peri - 78114 Magny Les Hameaux FRANCE
--|------------------------------------------------------
--| http://www.obry.org
--| "The best way to travel is by means of imagination"
--|
--| gpg --keyserver wwwkeys.pgp.net --recv-key C1082595
 
I

Ioannis Vranos

Tapio said:
STL is safer, but it cannot always be
used (eg. when interfacing to foreign code).


An example?

Another example:

int* f()
{
int i = 3;
int& l = *(new int);

l = i;
int* p = &i; // Should be int* p = &l;

return p;
}

int main()
{
int* p = f();
*p = 4;
return 0;
}

# g++ -Wall -o temp temp.cc
#

Not even a warning and the program does not crash on my system! Valgrind
revealed the error (and thought it was a G++ bug).


Strictly speaking one shouldn't use such variable names. However this is not easy to check
all those things. C++ aims to be an *enabling* language. For example one could have
written the following code for a system:


int* f()
{
// For setting panel indication.
int *p =reinterpret_cast <int *>(0x148);

// For reading external thermometer
volatile const int *r= reinterpret_cast<volatile const int *>(329);

// ...

return p;
}

int main()
{
int* p = f();
*p = 4;
return 0;
}
 
I

Ioannis Vranos

Ioannis said:
Perhaps you are right. If you have the standard, have a look at 3.9-2,
3.9-4, and 3.9-5 which I think agrees with you.


For thread completeness, I am posting the portable versions of the codes, as things got
clarified in another thread:


#include <new>

class SomeClass
{
};


int main()
{
unsigned char *array= new unsigned char[sizeof(SomeClass)];

SomeClass *p= new(array)SomeClass;

// ...

p->~SomeClass();

delete[] array;
}




#include <iostream>
#include <cstring>

class SomeClass
{
public:

double d;
int i;
float f;
long l;
};


int main()
{
using namespace std;

unsigned char *array= new unsigned char[sizeof(SomeClass)];

SomeClass obj= {1, 2, 3, 4};

memcpy(array, &obj, sizeof(obj));

SomeClass *p= static_cast<SomeClass *>( static_cast<void *>(array) );

cout<<p->d<<" "<<p->i<<" "<<p->f<<" "<<p->l<<"\n";

p->~SomeClass();

delete[] array;
}





#include <iostream>
#include <cstring>
#include <cstddef>

class SomeClass
{
public:

void somefunc() const { std::cout<<"somefunc() was called!\n"; }
};


int main()
{
using namespace std;

SomeClass obj;

unsigned char *p= reinterpret_cast<unsigned char *>(&obj);

unsigned char *array= new unsigned char[sizeof(obj)];

for(size_t i=0; i<sizeof(obj); ++i)
array= p;

SomeClass *obj2= static_cast<SomeClass *>( static_cast<void *>(array) );

obj2->somefunc();

obj2->~SomeClass();

delete[] array;
}
 
F

fabio de francesco

Peter said:
"Tapio Kelloniemi" <[email protected]> skrev i en meddelelse
What makes you believe they happen regularly in C++?
I see no real difference here between a good-quality C++ compiler and Ada.


/Peter

Is the following permitted in C++?

// file point.cpp

#include <iostream>

int *p = 0;

void fun()
{
int a = 1;
p = &a;
}

int main()
{
fun();
++(*p);
std::cout << *p << '\n';
return 0;
}

My compiler (GCC-3.4.1) doesn't raise any error with "g++ point.cpp
-Wall -W".

Shouldn't it have to complain?

fabio de francesco
 
I

Ioannis Vranos

fabio said:
Is the following permitted in C++?

// file point.cpp

#include <iostream>

int *p = 0;

void fun()
{
int a = 1;
p = &a;
}

int main()
{
fun();
++(*p);
std::cout << *p << '\n';
return 0;
}

My compiler (GCC-3.4.1) doesn't raise any error with "g++ point.cpp
-Wall -W".

Shouldn't it have to complain?


It is permitted. What you are incrementing above is the value stored in variable a.


Also check this:


#include <iostream>
#include <cstdlib>
#include <csignal>


inline void SigSegVHandler(int signal)
{
using namespace std;

cerr<<"Illegal memory operation!\n"<<"Exiting...\n";

exit(EXIT_FAILURE);
}

int main()
{
using namespace std;

signal(SIGSEGV, SigSegVHandler);

int *p= 0;

++(*p);

return 0;
}
 
F

fabio de francesco

fabio said:
and

Is the following permitted in C++?

// file point.cpp

#include <iostream>

int *p = 0;

void fun()
{
int a = 1;
p = &a;
}

int main()
{
fun();
++(*p);
std::cout << *p << '\n';
return 0;
}

My compiler (GCC-3.4.1) doesn't raise any error with "g++ point.cpp
-Wall -W".

Shouldn't it have to complain?

fabio de francesco

The following is more enjoable:

#include <iostream>

int *p = 0;

void fun()
{
int a = 1;
p = &a;
}

int fun2()
{
int b = 2;
return b *= b;
}

int main()
{
fun();
int c = fun2();
++(*p);
std::cout << *p << '\n';
std::cout << c << '\n';
return 0;
}

[toor@myhost]$ g++ point4.cpp -Wall -W
[toor@myhost]$ ./a.out
5
4

And now, trying to change some output statements:

int main()
{
fun();
int c = fun2();
std::cout << c << '\n';
++(*p);
std::cout << *p << '\n';
return 0;
}

[toor@myhost]$ g++ point4.cpp -Wall -W
[toor@myhost]$ ./a.out
4
12247261

I don't like anymore spending precious time with debuggers.

Ciao,

fabio de francesco
 
F

fabio de francesco

Ioannis said:
fabio said:
Is the following permitted in C++?

// file point.cpp
[skip code]

Shouldn't it have to complain?
It is permitted. What you are incrementing above is the value stored
in variable a.

Yes, with the only problem that the stack has already released space
reserved for that variable called "a".
Also check this:


#include <iostream>
#include <cstdlib>
#include <csignal>


inline void SigSegVHandler(int signal)
{
using namespace std;

cerr<<"Illegal memory operation!\n"<<"Exiting...\n";

exit(EXIT_FAILURE);
}

int main()
{
using namespace std;

signal(SIGSEGV, SigSegVHandler);

int *p= 0;

++(*p);

return 0;
}

Here you catch and handle a system SIGSEGV signal... I am missing the
point.

fabio de francesco
 
R

REH

Ioannis Vranos said:
Strictly speaking one shouldn't use such variable names. However this is not easy to check
all those things. C++ aims to be an *enabling* language. For example one could have
written the following code for a system:


int* f()
{
// For setting panel indication.
int *p =reinterpret_cast <int *>(0x148);

// For reading external thermometer
volatile const int *r= reinterpret_cast<volatile const int *>(329);

// ...

return p;
}

The Ada equivalent would be something like:

-- For setting panel indication.
p : integer;
for p'address use 16#148#;

-- For reading external thermometer
r : integer;
for r'address use 329;
pragma volatile(r);
 
I

Ioannis Vranos

fabio said:
Yes, with the only problem that the stack has already released space
reserved for that variable called "a".


Yes, however I think it is difficult for the compiler to protect from this at compile
time. Check my other example with pointers pointing to system-specific memory areas (my
example that includes the volatile pointer).
 
R

R Adsett

Yes, however I think it is difficult for the compiler to protect from this at compile
time. Check my other example with pointers pointing to system-specific memory areas (my
example that includes the volatile pointer).

Certainly far from impossible though, This is what I get from lint for
that

|
{
e:\cygwin\home\radsett\newlib-lpc\fram.c 98 Note 957: Function 'fun'
defined
without a prototype in scope

|
p = &a;
e:\cygwin\home\radsett\newlib-lpc\fram.c 100 Info 789: Assigning
address of
auto variable 'a' to static

Robert
 
G

Guest

Ioannis Vranos said:
You can't protect a bad programmer from doing bad programming, unless you forbid him to
continue programming. :)
You can provide tools that help the good programmer be a better
programmer. In my experience, Ada does just that.

I am one of those people who appeciates having tools that make
my job easier, whether for software development or for other
activities. I would rather use a socket wrench of the right
dimensions than an adjustable wrench. I prefer to use a bread
knife for my sourdough bread than a paring knife. I find it
easier, and safer, to use sharp axe for splitting logs than a
small hatchet. In each case, I can do the job with the less
effective tool, but the specialization of the tool makes my
life a little better.

There is rarely a programming problem I cannot express in
Ada. Sometimes I need to use one of the libraries instead
of the language itself. An example, in a separate thread,
is the use of decimal fraction exponent in a power expression.
The math library is required. This is a little safer that having
it directly in the language. It also simplifies the compiler a
bit. If I really need to do address arithmetic, I can, but I
rely on one of the child units of package System for this. That
library unit reduces the chances of my making stupid mistakes.

As Pascal Obry noted, Ada does forbid some things in the
core language. It forbids some unsafe things. However,
we can, if we wish, relax the rules of the language to do
unsafe things. There are all kinds of unchecked features,
and because they are unchecked, the programmer knows
the dangers. There are specialized packages that help
the programmer circumvent otherwise unsafe constructs.

It is easier to start with a language where the default for
most constructs is "safe" and relax the safety than it is
to start with a language such as C++ where the default is
generally "unsafe" and make it safer. In fact, with an
unsafe language there is little incentive for most programmers
to even try to find ways to make it more safe. I speak from
experience here. I have seen no end of C++ activity where
the programmers blithely grind out code where the compiler
cannot detect the unsafe parts of the program from those that
might be (we cannot be sure) safe.

Safe programming might be possible in C++. It is not common
in C++ programming practice. Unsafe programming might be
possible in Ada, but it is not common in Ada practice.

Richard Riehle
 
R

red floyd

forbid him to


You can provide tools that help the good programmer be a better
programmer. In my experience, Ada does just that.

We used to joke that a bad programmer could write FORTRAN IV code in any
language, even Ada!
 
M

Martin Dowie

red said:
We used to joke that a bad programmer could write FORTRAN IV code in any
language, even Ada!

I have seen a guy attempt to write COBOL in Ada - and he didn't even
know COBOL!!! :)
 

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

Forum statistics

Threads
473,769
Messages
2,569,581
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top