Variable incorrectly unbound when bound and used in binary match

Bernard Duggan bernie@REDACTED
Fri Mar 11 00:16:39 CET 2011


Reposting this (with slight modifications) that was posed in the questions list.  It seemed presumptuous to go straight to the bugs list, but the consensus seems to be that that's what this is:

So I've just run into an interesting little bit of behaviour that
doesn't seem quite right.  In the following code:
-----------------------------------------
-module(casetest).

-export([test/0]).

test() ->
      match(<<1, 2, 3, 4, 5, 6, 7, 8>>).

match(<<A:1/binary, B:8/integer, _C:B/binary, _Rest/binary>>) ->
      case A of
          B ->  wrong;
          _ ->  ok
      end.
-----------------------------------------
erlc gives me the warning

./casetest.erl:11: Warning: this clause cannot match because a previous
clause at line 10 always matches

(line 10 is the "B ->  wrong;" line).

And sure enough, if you run test/0 you get 'wrong' back.

That, in itself, is curious to me since by my understanding B should be
bound by the function header, and have no guarantee of being the same as
A.  I can't see how it could be unbound.

Doubly curious, is that if I stop using B as the size specifier of C,
like this:

match(<<A:1/binary, B:8/integer, _C:1/binary, _Rest/binary>>) ->

The warning goes away.  And the result becomes 'ok' (in spite of nothing
in the body having changed, and the only thing changing in the header
being the size of an unused variable at the tail of the binary).
Similarly, if I change the body of match/1 to this:

      Z = B,
      case A of
          Z ->  wrong;
          _ ->  ok
      end.

It also works.

So, yeah, it kinda looks like a bug.

Cheers,

Bernard



More information about the erlang-bugs mailing list