To the contrary, labels and breaks are the better design because they are far clearer than testing for termination in each outer loop. Get more than two loops deep and your problem suddenly becomes unmanageable without labels and breaks.
However, if there are other actions like logging or reporting that are occurring it may be better to not use them. Here's some Ada:
Outer: loop
Inner: loop
Handle_Head: declare
Head : Human_Head;
begin
Acquire_Head (Head); -- Entry will block until head is acquired.
exit Inner when Head = No_Head;
exit Outer when Head.Exploded;
Log ("Head unexploded.");
exception
when Brain_Error =>
Log ("Brain deficiency detected.");
end Handle_Head;
end loop Inner;
Log ("Head exploded.");
end loop Outer;