嵌めら…(ええとええと)…れた

月U9の「れ」が覚えられなくて困る。そんな話はどうでもいいです。
久しぶりにAdaの言語仕様に嵌められました。

with Ada.Text_IO; use Ada.Text_IO;
with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;
procedure Test is
   A : String (10 .. 20);
   B : String := "ABC";
   C : String := "";
   D : String (1 .. 0);
   AA : String := A & A;
   AB : String := A & B;
   AC : String := A & C;
   AD : String := A & D;
   BA : String := B & A;
   BB : String := B & B;
   BC : String := B & C;
   BD : String := B & D;
   CA : String := C & A;
   CB : String := C & B;
   CC : String := C & C;
   CD : String := C & D;
   DA : String := D & A;
   DB : String := D & B;
   DC : String := D & C;
   DD : String := D & D;
begin
   Put(AA'First); Put(AB'First); Put(AC'First); Put(AD'First); New_Line;
   Put(BA'First); Put(BB'First); Put(BC'First); Put(BD'First); New_Line;
   Put(CA'First); Put(CB'First); Put(CC'First); Put(CD'First); New_Line;
   Put(DA'First); Put(DB'First); Put(DC'First); Put(DD'First); New_Line;
end Test;

問題。上記のプログラムの出力はどうなるでしょうか?
回答。

         10         10         10         10
          1          1          1          1
         10          1          1          1
         10          1          1          1

左下の、CAとDAの10、違和感ありません?ねえ?
かいせつ。predefinedの&演算子は、基本的に左辺の配列の開始インデックスを採用しますが、左辺の長さが0だった場合のみ、右辺をそのまま返します。
http://adaic.org/standards/05rm/html/RM-4-5-3.html

If the left operand is a null array, the result of the concatenation is the right operand. Otherwise, the lower bound of the result is determined as follows:

やめてください。統一しておいてくれ。誰が喜ぶんだこれ。
実行時にも余計な条件分岐が必要になるだけでしょうに……。
A : String := B(1 .. C) & D;なんてやっててBが定数だからまたは固定長だから1から開始決めうちなんてしてますと、Cが0で外からやってきたDがとんでもない範囲を持ってたりして死ねます。
けつろん。サボらずに'Firstを使おう。