[erlang-questions] bit syntax: 0-sized segments
Kostis Sagonas
kostis@REDACTED
Fri Mar 8 01:09:20 CET 2013
On 03/08/2013 12:09 AM, Richard A. O'Keefe wrote:
> Surely zero-length segments *have* to be allowed?
>
> Suppose you have
> <<N:16, B:N/bytes, R/binary>> = Whatever
>
> Is this supposed to crash if N = 0?
> Why?
>
> I cannot understand what is supposed to be 'weird' about
> zero-length segments.
Perhaps the exact issue that I find slightly "weird" was too subtle in
my mail.
First of all, note that all your examples involve binary segments. In
this case (and in bitstrings, which is its generalization) one could
argue that there is a perfectly sensible "solution" to the matching
problem, namely the empty bitstring as can be seen below.
9> <<X:0/binary>> = <<>>.
<<>>
10> X.
<<>>
IMO, the solution to the previous matching makes sense because binaries
(bitstrings) get "flattened" out when nested in other ones: for any
binary (bitstring) B, the binary (bitstring) <<B/bits>> is the same as
B. Also, for all bitstrings B the following matching succeeds and
returns X = B.
B = <<...SOME BITSTRING...>, N = bit_size(B), <<X:N/bitstring>> = B.
Note that B = <<>> and <<X:0/binary>> is just a special case of the
above matching.
So far so good.
When one moves to integer segments the above property does not make much
sense anymore (esp. since bit_size is not defined for anything other
than bitstrings). In particular, the current implementation of binary
pattern matching has chosen to return an "arbitrary" integer, namely 0,
as the result. I can may well see that many would consider the following
binding for X to 0 a bit weird.
1> <<X:0/integer>> = <<42:0>>.
<<>>
2> X.
0
Moreover, the situation is arguably even more weird for floats:
3> <<F:0/float>> = <<42:0>>.
<<>>
4> F.
0.0
especially so since one cannot even write something like <<42:0/float>>
(or even <<3.1415:0/float>>) as a construction.
I am not so convinced that pattern matching with 0-size segments make
sense for types other than bitstrings (binaries).
Kostis
> Look at example 4 from the Bit Syntax documentation:
>
> -define(IP_VERSION, 4).
> -define(IP_MIN_HDR_LEN, 5).
>
> DgramSize = byte_size(Dgram),
> case Dgram of
> <<?IP_VERSION:4, HLen:4, SrvcType:8, TotLen:16,
> ID:16, Flgs:3, FragOff:13,
> TTL:8, Proto:8, HdrChkSum:16,
> SrcIP:32,
> DestIP:32, RestDgram/binary>> when HLen>=5, 4*HLen=<DgramSize ->
> OptsLen = 4*(HLen - ?IP_MIN_HDR_LEN),
> <<Opts:OptsLen/binary,Data/binary>> = RestDgram,
> ...
> end.
>
>
> If there are no options, so that HLen == IP_MIN_HDR_LEN and OptsLen == 0,
> this reduces to
> <<Opts:0/binary,Data/binary>> = RestDgram.
>
> Is there anything "weird" about a datagram with no options?
>
> If the issue is construction rather than matching,
> is there anything "weird" about constructing a datagram with no options?
>
> Zero is a perfectly good size. It would be a serious defect in Erlang
> if it _didn't_ allow zero-size segments. ....
More information about the erlang-questions
mailing list