RE: let binding with c

[email protected]
Newsgroups gmane.lisp.scheme.bigloo
Organization Inria
Message-ID <[email protected]>
Hi Michel,

> Hi Manuel,
> 
> You can compile the files I copy/paste in the email, below  =  "bigloo -c failc.c ;   bigloo fail.scm failc.o -o toto"
> Then execute, and see the result:
> > toto
> dataOK1 = 12346789-123456789-123456789-, len is: 30
> dataOK2 = 12346789-123456789-123456789-, len is: 30
> data-not-KO = 1234, len is: 30
> 
> Let me comment:
> - we have a C structure, a kind of buffer with 2 fields 'data' and 'length'
> And we have a C function that set 'data' to a buf (filled) in the global area, and set 'len' to 30.
> In the scheme part, we construct an instance of  c-struct and call the c-function that initialize  it; in a  'let*'
> then, we try to retrieve the data content in the scheme, thanks to 3 bindings,  corresponding to 3 trials.
> I would expect 3 identical  results. I can't explain why the latest trial is not ok.
> It looks like the 'if' says 'true' in the 3rd binding , but we expect 'false' that leads to a correct bind of the data.
> ...at the same time , a similar 'if' in the 2nd binding works fine ... that's even more strange.
> 
> Tell me if you need more info. 
> Thanks, regards,
> Michel
This is indeed very subtle... and confusing. Here is the explanation.
Local variables are typed by the compiler. On a let assignment, Bigloo
assigns the type of the variable with the type of the rhs expression.
In your example:

   (let* (...
          (dataOK1 (pragma::bstring ...))
          (dataOK2 (if (equal? (c_struct*-len my-struct) 999)
		       "we should not get this because -len is not 999"
		       (pragma::bstring ...)))
          (data-not-KO (if (equal? (c_struct*-len my-struct) 999)
			   (c_struct*-data my-struct))
			   (pragma::bstring "fool( $1, $2 )" (c_struct*-data my-struct)  (c_struct*-len my-struct))))

Variables dataOK1 and dataOK2 are assigned the type ::bstring (both rhs
expressions are bstring) but data-no-KO is assigned a type ::string
because on a if joint point Bigloo prefers the most efficient type.
Here is select ::string (the then branch of your if) against ::bstring
(the else part of the if). Before displaying the data-no-KO in the
expression

  (print "data-not-KO = " data-not-KO ", len is: " (c_struct*-len my-struct))

The variable data-no-KO has to be compiled back to ::bstring before
being sent to print. For that it uses the conversion function string_to_bstring
that stops after a (char)0 and this is why print ends up with a string of
length 4.

To solve the problem, you can explicitly type the variable, for instance
with:

  (data-not-KO::bstring (if (equal? ...)))

I agree that all this is very confusing but unfortunately, I'm not sure
it can be changed.

Cheers,

-- 
Manuel
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.