Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 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
8-38961
SergeyDon
2003-10-11 15:35
2004.02.13
ламерский вопрос: чем отличается использование OpenGL от DirectX?


3-38684
Goida
2004-01-14 17:43
2004.02.13
ADO на WindowsNT


14-39083
Ломброзо
2004-01-24 00:13
2004.02.13
За Родину, за Путинда!


1-38894
Кен
2004-02-05 01:42
2004.02.13
Как фильтровать дерево ? По шаблону.


6-38994
Dark Elf
2003-09-10 12:15
2004.02.13
Работа с почтой





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский