C++ имеет непринужденный подход к тому, где переменные области видимости могут быть объявлены или определены. В то время как в C нужно было объявлять все переменные в начале области видимости, в C++ их можно объявлять где угодно по пути, руководствуясь эмпирическим правилом делать это как можно позже. Это более эффективно — подумайте о вызовах конструктора/деструктора, которые вы можете защитить — и увеличивает вероятность того, что вы сможете объявить его const.

Ада делает строгое различие между разделами, в которых разрешены объявления, и разделами, которые могут содержать логику выполнения. В этом смысле это больше похоже на C, что в начале области необходимо делать объявления.

Давайте посмотрим на небольшой пример:

declare
   I : Integer;
begin
   I := 1;
end;

В этом простом случае объявляется переменная I, а затем ей присваивается значение 1.

Но блок declare также позволяет определять переменные (т. е. присваивать им начальное значение).

declare
   I : Integer := 42;
begin
   I := I / 2;
end;

Таким образом вполне возможно выполнять код в блоке declare. И исполняемый код может в конечном итоге привести к возникновению исключения. Затем мы могли бы ввести обработчик исключений, чтобы справиться с этим.

declare
   I : Integer := Function_That_Might_Raise_An_Exception;
begin
   I := I + 1;
exception
   when E : others =>
      Put_Line (Exception_Information (E));
end;

Выглядит хорошо, но не делает то, что мы хотим. Он будет обрабатывать исключения только из блока begin, но не из этого блока declare. Примечание: I хорошо виден в блоке обработчика исключений.

Чтобы покрыть эти случаи, нужно ввести еще один слой.

begin
   declare
      I : Integer := Function_That_Might_Raise_An_Exception;
   begin
      I := I + 1;
   end;
exception
   when E : others =>
      Put_Line (Exception_Information (E));
end;

Это уже сложно читать, и становится еще хуже, когда вы рассматриваете подпрограммы, потому что у них есть декларативный раздел по умолчанию, но нет функционального блока попытки, как в C++.

procedure Foo
is
   --  This declarative block is lost.
begin
   declare
      I : Integer := Function_That_Might_Raise_An_Exception;
   begin
      I := I + 1;
   end;
exception
   when E : others =>
      Put_Line (Exception_Information (E));
end Foo;

Сравните это со случаями C++:

void Foo try {
  int i{function_that_might_throw_an_exception()};
  i += 1;
}
catch (std::exception& e) {
   std::cout << e.what() << std::endl;
}

Или это:

try {
  int i{function_that_might_throw_an_exception()};
  i += 1;
}
catch (std::exception& e) {
   std::cout << e.what() << std::endl;
}

Такие инструменты, как CodePeer, которые могут выполнять глобальный статический анализ программ на языке Ada, должны уметь обнаруживать случаи, когда блок объявления может вызвать исключение, и помечать их, чтобы можно было соответствующим образом разместить обработчики исключений.