Форум: "Основная";
Текущий архив: 2004.02.13;
Скачать: [xml.tar.bz2];
ВнизПроблемы с компилятором 2 Найти похожие ветки
← →
Тимохов (2004-02-05 10:57) [0]Почитав первый релиз поста про проблемы с компилятором, решил составить свой вопрос по обозначенной теме.
Например, есть код:
type
tenum = (enA, enB, enC);
function EnumAsStr(enum: tenum): string;
begin
case enum of
enA: Result := "A";
enB: Result := "B";
enC: Result := "C";
end;
end;
в данном случае копилятор дает предупрежедение о том, что result может быть не определен.
Конечно, этот метод можно переделать под константный массив строк и без case. Но, хотелось бы остановиться именно на таком варианте - т.к. это сильно урезанный вариант реальной программы, а там без того, чтобы вычислять result в case обойтись нельзя.
Вопрос. Как относится к такому соощению компилятора? Как по Вашему мнению компилятор видит ситуацию, когда есть возможность ошибки?
← →
Никто (2004-02-05 11:04) [1]case enum of
enA: Result := "A";
enB: Result := "B";
else
Result := "C";
end;
← →
pasha_golub (2004-02-05 11:07) [2]Никто (05.02.04 11:04) [1]
Совершенно правильный выход, ИМХО.
← →
Gero (2004-02-05 11:09) [3]Можно это реализовать так:
case enum of
enA: Result := "A";
enB: Result := "B";
else Result := "C";
end;
Или писать сначала Result := "". А потом все остальное.
Наверно это недоработка Borland, ведь компилер не видит, что других значений, кроме перечисленых в case, enum принять не может. Хотя я могу и ошибаться
← →
Gero (2004-02-05 11:10) [4]Блин, я опоздал с постом :)
← →
Тимохов (2004-02-05 11:12) [5]
> pasha_golub © (05.02.04 11:07) [2]
> Никто (05.02.04 11:04) [1]
Полностью согласен с правильностью выхода - сам так и делаю.
Кто-то тут говорил, что компилятор не ошибается.
Очень интересно было бы получить ответ на этот вопрос:
"Как по Вашему мнению компилятор видит ситуацию, когда есть возможность ошибки?"
Ясно дело что в случае
function a(b: integer): integer;
begin
if b = 0 then result := 1;
end;
все очевидно - копмилятор не может знать точно, что я передам в "а" в параметре "b". Но в исходном вопросе мне, например, абсолютно не ясно, как может быть ошибка. :(((
← →
Никто (2004-02-05 11:12) [6]>> ведь компилер не видит, что других значений, кроме перечисленых в case, enum принять не может
enum := tenum(10);
← →
Тимохов (2004-02-05 11:13) [7]
> Наверно это недоработка Borland,
Во-во - у меня такое же ощущение...
← →
Тимохов (2004-02-05 11:15) [8]
> Никто (05.02.04 11:12) [6]
> >> ведь компилер не видит, что других значений, кроме перечисленых
> в case, enum принять не может
>
> enum := tenum(10);
Это мысль, самому в голову не пришла...
← →
Verg (2004-02-05 11:18) [9]Range Checking включи, да?
← →
McSimm (2004-02-05 11:19) [10]В конечном счете tenum это просто байт, поэтому возможность ошибки все же есть, например приведение типов.
Поэтому
case enum of
enA: Result := "A";
enB: Result := "B";
else
Result := "C";
end;
конечно правильный вариант, но я предпочитаю более придирчивые конструкции
case enum of
enA: Result := "A";
enB: Result := "B";
enC: Result := "C";
else
raise ....
end;
← →
Mystic (2004-02-05 11:20) [11]Delphi 5 у меня ни подсказки, ни предупреждения на этот код не выдал. Более того, не было хинтов на следующий код:
type
TEnum = (enA, enB, enC);
function EnumAsStr(Enum: TEnum): string;
begin
ShowMessage(Result);
case Enum of
enA: Result := "A";
enB: Result := "B";
enC: Result := "C";
end;
end;
procedure TMainForm.TestBtn2Click(Sender: TObject);
var
St: string;
begin
St := "Test";
St := EnumAsStr(enA);
ShowMessage(St);
end;
При этом, как и предполагалось, было показано вначале "Test", а потом "A". в принципе, это естественно, поскольку string относиться к типам, требующим инициализации, посему получить Hint о неопределенном значении трудно...
Иное дело код:
type
TEnum = (enA, enB, enC);
function EnumAsStr(Enum: TEnum): Integer;
begin
case Enum of
enA: Result := 5;
enB: Result := 6;
enC: Result := 12;
end;
end;
Здесь да, есть предупреждение. В принципе вполне оправдано, так как, имхо, разработчики Delphi больше придерживались принципа --- лучше дать лишнее предупреждение, чем его не дать совсем. С такими ошибками я борюсь, например, так:
type
TEnum = (enA, enB, enC);
function EnumAsStr(Enum: TEnum): Integer;
begin
case Enum of
enA: Result := 5;
enB: Result := 6;
enC: Result := 12
else raise EAssertionFailed.Create("Test");
end;
end;
← →
Rouse_ (2004-02-05 11:24) [12]Немного дополню McSimm - а
case enum of
enA: Result := "A";
enB: Result := "B";
enC: Result := "C";
else
begin
Result := "Unknown";
raise ....
end;
end;
Этот вариант более хорош тем, что с случае изменения базового типа tenum другим программистом мы сразу обнаружим ошибку...
← →
Никто (2004-02-05 11:25) [13]Range checking сhecks that array and string subscripts are within bounds.
← →
Тимохов (2004-02-05 11:27) [14]
> Delphi 5 у меня ни подсказки, ни предупреждения на этот
> код не выдал. Более того, не было хинтов на следующий код:
Виноват.
Вы правы. Писал пример тут и потому, забыл, что такое предупреждение на строки не дается. Предупреждение будет, если возвращаемое значение integer.
Всем.
Спасибо. Самое для меня ценное было появившееся первым соображение Никто (05.02.04 11:12) [6] - самому в голову это не приходило.
Больше воросов нет...
← →
Mystic (2004-02-05 11:42) [15]I>> Тимохов © (05.02.04 11:27) [14]
Запутать компилятор можно:
function FindPositiveMin(const X: array of Integer): Integer;
var
IsFound: Boolean;
I: Integer;
begin
IsFound := False;
for I := Low(X) to High(X) do
begin
if X[I] > 0 then
if not IsFound then
begin
Result := X[I];
IsFound := True;
end
else
if X[I] < Result then Result := X[I];
end;
if not IsFound then Result := -1;
end;
Не запутаться бы только самому...
← →
Gero (2004-02-05 11:46) [16]> Mystic ©
А зачем его запутывать? ;)
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2004.02.13;
Скачать: [xml.tar.bz2];
Память: 0.48 MB
Время: 0.011 c