Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2004.02.13;
Скачать: CL | DM;

Вниз

Проблемы с компилятором 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;
Скачать: CL | DM;

Наверх




Память: 0.51 MB
Время: 0.026 c
1-38891
WebErr
2004-02-03 17:40
2004.02.13
Директива friend в Object Pascal !!!


1-38797
uu
2004-02-03 12:40
2004.02.13
Разряд


1-38942
Pavel
2004-02-04 09:19
2004.02.13
Глючный Delphi


1-38931
Onward
2004-02-04 11:18
2004.02.13
WriteComm/ReadComm


3-38733
Санек
2004-01-24 19:13
2004.02.13
Таблица с вычисляемыми вертикальными полями ?