Неприятная особенность компилятора

105 views
Skip to first unread message

Ilya Shcherbak

unread,
Jul 29, 2013, 7:17:14 AM7/29/13
to erlang-...@googlegroups.com
Столкнулся с таким, позволю себе сказать, багом. При компилировании Erlang модуля не во всех кейсах выводится warning типа:
Warning: this clause cannot match because a previous clause

Таким примером может служить функция от двух аргументов, где эти аргементы - рекорды. Если мы в верхнем кейсе указываем рекорды,
 ничего в них не матча, а нижний делаем такой же, но матчим по полю одного из рекорда, компилятор нам не скажет, что во второй кейс мы никогда не попадем.

Пример:
-module('1'). -record(record_1,{arg}). -record(record_2,{}). -export([foo/2]). foo(#record_1{},#record_2{})-> {ok,1}; foo(#record_1{arg=1},#record_2{}) -> {ok,2}. :~/rep/vcs/apps/vcs_core/src$ erl Erlang R15B02 (erts-5.9.2) [source] [64-bit] [smp:8:8] [async-threads:0] [hipe] [kernel-poll:false] Eshell V5.9.2 (abort with ^G) 1> c("1.erl"). {ok,'1'}


Хотя на более простой код, компилятор охотно ругнется:
-module('1'). -record(record_1,{arg}). -record(record_2,{}). -export([foo/2]). foo(#record_1{},_)-> {ok,1}; foo(#record_1{arg=1},#record_2{}) -> {ok,2}. :~/rep/vcs/apps/vcs_core/src$ erl Erlang R15B02 (erts-5.9.2) [source] [64-bit] [smp:8:8] [async-threads:0] [hipe] [kernel-poll:false] Eshell V5.9.2 (abort with ^G) 1> c("1.erl"). 1.erl:17: Warning: this clause cannot match because a previous clause at line 15 always matches {ok,'1'}

Говорить о том почему это опасно, я думаю излишне. :)

Денис Фахртдинов

unread,
Jul 29, 2013, 7:45:21 AM7/29/13
to erlang-...@googlegroups.com
А разве такой код, как
foo(#record_1{},#record_2{})->
    {ok,1};
Не будет матчить по "пустому" рекорду, то есть по рекорду с дефолтными значениями?


29 июля 2013 г., 15:17 пользователь Ilya Shcherbak <tth...@gmail.com> написал:
--
--
Страница рассылки: http://groups.google.com/group/erlang-russian
Новости: http://erlanger.ru
Чат: xmpp://erl...@conference.jabber.ru
Чат для оффтопа: xmpp://erlang...@conference.jabber.ru
Правила, действующие в чате и рассылке: http://erlanger.ru/ru/erlang-at-conference-jabber-ru
 
Написать письмо: erlang-...@googlegroups.com
Отписаться: erlang-russia...@googlegroups.com
---
Вы получили это сообщение, поскольку подписаны на группу Erlang по-русски.
 
Чтобы отказаться от подписки на эту группу и перестать получать из нее сообщения, отправьте электронное письмо на адрес erlang-russia...@googlegroups.com.
Настройки подписки и доставки писем: https://groups.google.com/groups/opt_out.
 
 

Max Lapshin

unread,
Jul 29, 2013, 8:11:22 AM7/29/13
to erlang-...@googlegroups.com
Очень похоже действительно на какой-то баг.

Напиши в основную рассылку.

Gleb Peregud

unread,
Jul 29, 2013, 8:29:49 AM7/29/13
to erlang-...@googlegroups.com

Это не баг. Рекорды в заголовках и кейсах, если в них значение не прописано для данного поля, матчатся с любым значением этого поля. Т.е.

func(#record{}) ->
  ok.

равнозначно

func(#record{param1=_, ..., paramN=_}) ->
  ok.

On 29 Jul 2013 14:11, "Max Lapshin" <max.l...@gmail.com> wrote:
Очень похоже действительно на какой-то баг.

Напиши в основную рассылку.

--

Dmitrii Dimandt

unread,
Jul 29, 2013, 8:30:33 AM7/29/13
to erlang-...@googlegroups.com
Компилятор имеет право переставлять function clauses, если это не влияет на смысл программы. Возможно, тут срабатывает это.


и

Очень похоже действительно на какой-то баг.

Напиши в основную рассылку.

Gleb Peregud

unread,
Jul 29, 2013, 8:31:16 AM7/29/13
to erlang-...@googlegroups.com

Ой, не дочитал. Да, похоже на баг. Компилятор должен здесь тоже ругаться

Dmitrii Dimandt

unread,
Jul 29, 2013, 8:31:43 AM7/29/13
to erlang-...@googlegroups.com
Перечитал вопрос и понял, что мои ссылки к этому не имеют отношения :)

Ilya Shcherbak

unread,
Jul 29, 2013, 9:13:42 AM7/29/13
to erlang-...@googlegroups.com
Ну конечно нет.

понедельник, 29 июля 2013 г., 18:45:21 UTC+7 пользователь Denis F. написал:
Reply all
Reply to author
Forward
0 new messages