Binding variables from binaries in function headers

Bernard Duggan <>
Wed Mar 9 03:48:02 CET 2011


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.

Bug?  Feature?  Me making an obvious blunder that nobody I've shown this 
to can spot?

Cheers,

Bernard


More information about the erlang-questions mailing list