A proper language comparison...
bearophile
bearophileHUGS at lycos.com
Thu Jul 25 19:19:06 PDT 2013
Walter Bright:
> It's done by the hardware (putting a "no-access" page at the
> end of the stack). There's nothing unsafe about it.
>
>
>> no variable-sized stack-allocated arrays that help a bit
>> created bounded collections,
>
> I don't see how that is a safety issue.
In my opinion where you allocate your data influences the
"safety" of your program, but it's not easy for me to tell
exactly in what direction such influence is.
If you allocate too much data on the stack this could cause stack
overflow. As you say a stack overflow is memory safe, but if your
program is doing something important, a sudden crash could be
regarded as dangerous for the user. You don't want a stack
overflow in the code that controls your car brakes (this is not a
totally invented example).
Having variable-sized stack-allocated arrays encourages you to
put more data on the stack, increasing the risk of stack
overflows.
On the other hand, if you only have fixed-sized stack-allocated
arrays, you could allocate a fixed size array on the stack and
then use only part of it. This waste of stack space increases the
probability of stack overflow. A variable-sized stack-allocated
array allows you to waste no stack space, and avoid those stack
overallocations.
If you are using a segmented stack as Rust, stack overflows
become less probable (it becomes more like a malloc failure),
because the stack is able to become very large when needed. I
think Rust needs that elastic stack because in such language it's
easy to allocate all kind of stuff on the stack (unlike in D).
- - - - - - - - - -
Ada is safer compared to D for other things. One of them is the
little mess of integer division that D has inherited from C.
This is how the Ada compiler forces you to write a certain
division:
procedure Strong_Typing is
Alpha : Integer := 1;
Beta : Integer := 10;
Result : Float;
begin
Result := Float (Alpha) / Float (Beta);
end Strong_Typing;
In D you could write:
int a = 1;
int b = 10;
double r = a / b;
and in r you will not see the 0.1 value. This is a C design
mistake that I have seen bite even programmers with more than 2
years of programming experience with C-like languages. Perhaps
having "/" and "div" for floating point and integer divisions in
D could avoid those bugs.
Another mistake is D inheriting the C99 semantics of % that is
suboptimal and bug-prone.
(Both mistakes are fixed in Python3, by the way, despite I don't
fully like the Python3 division).
- - - - - - - - - -
In Ada there is 'others' to define the value of the array items
that you are not specifying, this removes the bugs discussed in
Issue 3849:
declare
type Arr_Type is array (Integer range <>) of Integer;
A1 : Arr_Type := (1, 2, 3, 4, 5, 6, 7, 8, 9);
begin
A1 := (1, 2, 3, others => 10);
end;
'others' is usable even for struct literals, when you don't want
to specify all fields:
type R is record
A, B : Integer := 0;
C : Float := 0.0;
end record;
V3 : R => (C => 1.0, others => <>);
For D I suggested array syntax like:
int[$] a1 = [1, 2, 3];
int[10] a2 = [1, 2, 3, ...];
void main() {}
where the "..." tells the compiler the programmer wants it to
fill those missing values with their default init.
Ada Concurrency is quite refined, and it's kind of safe.
Bye,
bearophile
More information about the Digitalmars-d
mailing list