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

Reply via email to