caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
* CAMLreturn does not work for floats between 0 and 1 ?
@ 2007-02-16 14:46 Matthieu Dubuget
  2007-02-16 15:09 ` [Caml-list] " Daniel Bünzli
  2007-02-17  0:30 ` Jacques Garrigue
  0 siblings, 2 replies; 8+ messages in thread
From: Matthieu Dubuget @ 2007-02-16 14:46 UTC (permalink / raw)
  To: caml-list

Hello list!

I'm sure I'm doing something bad. But I can't find out where?

The problem is that when I CAMLreturn float : r with   0. < r < 1.,
I get 0.00000000.

The OCaml functions are in testdouble. The main test is in testd.c.

It prints (ses main function at the end) :

I=5:
f: r(5)=0.00500                         <--------- values just returned
from OCaml
f2: r(5)=5.00000
r1: f(5)=0.00000                       <--------------  WHY?
r2: f2(5)=5.00000


I reproduced this with version 3.09.3 of cygwin OCaml and godi (Ubuntu)
ocaml.

Really I do not understand what is going on?

Salutations

Matt

-----------------------  testdouble.ml ---------------------
let f i = float i  /. 1000.
let f2 i = float i
let _ = Callback.register "f" f
and _ = Callback.register "f2" f2
-----------------------------------------------------------
----------------   testd.c    -------------------------------------

#include <stdio.h>

#include <caml/mlvalues.h>
#include <caml/alloc.h>
#include <caml/memory.h>
#include <caml/callback.h>

static int ms_visus_init_done = 0;

void ms_visus_init (void)
{
  char *vide[2];

  vide[0] = "bof";
  vide[1] = NULL;

  if (!ms_visus_init_done)
    {
      caml_startup (vide);
      ms_visus_init_done = 1;
    }
}


double f (int i){
  CAMLparam0 ();
  double r; 
  static value *cr = NULL;
  if (cr == NULL) cr = caml_named_value("f");
  r = Double_val(caml_callback(*cr, Val_int(i)));
  printf("f: r(%d)=%.5f\n", i, r);
  CAMLreturn(r);
}

double f2(int i){ 
  CAMLparam0 ();
  double r;
  static value *cr = NULL;
  if (cr == NULL) cr = caml_named_value("f2");
  r = Double_val(caml_callback(*cr, Val_int(i)));
  printf("f2: r(%d)=%.5f\n", i, r);
  CAMLreturn(r);
}

int main(){
  int i;
  double r1, r2;
  ms_visus_init();

  i=5;
  printf("I=%d:\n",i);
  r1 = f(i);
  r2 = f2(i);
  printf("r1: f(%d)=%.5f\n", i, r1);
  printf("r2: f2(%d)=%.5f\n", i, r2);
 

  exit (0);
}
-----------------------------------------------------





^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [Caml-list] CAMLreturn does not work for floats between 0 and 1 ?
  2007-02-16 14:46 CAMLreturn does not work for floats between 0 and 1 ? Matthieu Dubuget
@ 2007-02-16 15:09 ` Daniel Bünzli
  2007-02-16 16:20   ` Matthieu Dubuget
  2007-02-17  0:30 ` Jacques Garrigue
  1 sibling, 1 reply; 8+ messages in thread
From: Daniel Bünzli @ 2007-02-16 15:09 UTC (permalink / raw)
  To: matthieu.dubuget; +Cc: caml-list


Le 16 févr. 07 à 15:46, Matthieu Dubuget a écrit :

> I'm sure I'm doing something bad. But I can't find out where?

CAMLreturn and CAMLparam0 macros are used in functions that are  
called from ocaml land and return a value in ocaml land. You should  
not use them for your functions called in C land and returning a  
value in C land (see section 18.7.2 of the manual).

Best,

Daniel


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [Caml-list] CAMLreturn does not work for floats between 0 and 1 ?
  2007-02-16 15:09 ` [Caml-list] " Daniel Bünzli
@ 2007-02-16 16:20   ` Matthieu Dubuget
  2007-02-16 17:02     ` Mathias Kende
  2007-02-16 17:07     ` Daniel Bünzli
  0 siblings, 2 replies; 8+ messages in thread
From: Matthieu Dubuget @ 2007-02-16 16:20 UTC (permalink / raw)
  To: caml-list

Daniel Bünzli a écrit :
>
> Le 16 févr. 07 à 15:46, Matthieu Dubuget a écrit :
>
>> I'm sure I'm doing something bad. But I can't find out where?
>
> CAMLreturn and CAMLparam0 macros are used in functions that are called
> from ocaml land and return a value in ocaml land. You should not use
> them for your functions called in C land and returning a value in C
> land (see section 18.7.2 of the manual).
OK. Thanks. But this is not all clear for me.

Suppose that I have to construct one or more value(s) to pass them to
OCaml land. I do have to use CAMLlocal macros for that, don't I.
Can use them without CAMLparam and CAMLreturn macros?

Salutations

Matt


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [Caml-list] CAMLreturn does not work for floats between 0 and 1 ?
  2007-02-16 16:20   ` Matthieu Dubuget
@ 2007-02-16 17:02     ` Mathias Kende
  2007-02-16 17:07     ` Daniel Bünzli
  1 sibling, 0 replies; 8+ messages in thread
From: Mathias Kende @ 2007-02-16 17:02 UTC (permalink / raw)
  Cc: caml-list

If you're writing a function called by OCaml, then you should use
CAMLparam and CAMLreturn macros (and the function will take only
parameters of type value (and one at least)). But if your function is
called by C code then it must follows the normal convention.

To send a value to Caml (with caml_callback for exemple) you should
create it with the Val_* functions if it is a simple block (int or bool)
or with the caml_alloc* ones in other cases.

Sincerely.
Mathias

Le vendredi 16 février 2007 à 17:20 +0100, Matthieu Dubuget a écrit :
> Daniel Bünzli a écrit :
> >
> > Le 16 févr. 07 à 15:46, Matthieu Dubuget a écrit :
> >
> >> I'm sure I'm doing something bad. But I can't find out where?
> >
> > CAMLreturn and CAMLparam0 macros are used in functions that are called
> > from ocaml land and return a value in ocaml land. You should not use
> > them for your functions called in C land and returning a value in C
> > land (see section 18.7.2 of the manual).
> OK. Thanks. But this is not all clear for me.
> 
> Suppose that I have to construct one or more value(s) to pass them to
> OCaml land. I do have to use CAMLlocal macros for that, don't I.
> Can use them without CAMLparam and CAMLreturn macros?
> 
> Salutations
> 
> Matt
> 
> _______________________________________________
> Caml-list mailing list. Subscription management:
> http://yquem.inria.fr/cgi-bin/mailman/listinfo/caml-list
> Archives: http://caml.inria.fr
> Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
> Bug reports: http://caml.inria.fr/bin/caml-bugs


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [Caml-list] CAMLreturn does not work for floats between 0 and 1 ?
  2007-02-16 16:20   ` Matthieu Dubuget
  2007-02-16 17:02     ` Mathias Kende
@ 2007-02-16 17:07     ` Daniel Bünzli
  2007-02-16 19:19       ` Matthieu Dubuget
  1 sibling, 1 reply; 8+ messages in thread
From: Daniel Bünzli @ 2007-02-16 17:07 UTC (permalink / raw)
  To: matthieu.dubuget; +Cc: caml-list


Le 16 févr. 07 à 17:20, Matthieu Dubuget a écrit :

> Suppose that I have to construct one or more value(s) to pass them to
> OCaml land. I do have to use CAMLlocal macros for that, don't I.

It depends. If you _allocate_ (e.g. ints are not allocated) a caml  
value \x13v1 then another caml v2 and then modify v1, you need to keep a  
hand on v1 with CAMLparam because it may move when you allocate v2.  
If you allocate only a single value then there is no need to do it  
(unless some code you call may invoke the gc before you use v1).

> Can use them without CAMLparam and CAMLreturn macros?

No. But I never did the C -> ocaml -> C way so I don't really know  
how to proceed. The first thing that comes to mind is to store the  
result in a variable given to  the function.

void f1 (int i, double *result) {
	CAMLparam...
	*result = ...
	CAMLreturn0;
}

Maybe there's another way, I don't know.

Daniel


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [Caml-list] CAMLreturn does not work for floats between 0 and 1 ?
  2007-02-16 17:07     ` Daniel Bünzli
@ 2007-02-16 19:19       ` Matthieu Dubuget
  2007-02-16 22:28         ` Daniel Bünzli
  0 siblings, 1 reply; 8+ messages in thread
From: Matthieu Dubuget @ 2007-02-16 19:19 UTC (permalink / raw)
  To: Caml List

Daniel Bünzli a écrit :
>
> Le 16 févr. 07 à 17:20, Matthieu Dubuget a écrit :
>
>> Suppose that I have to construct one or more value(s) to pass them to
>> OCaml land. I do have to use CAMLlocal macros for that, don't I.
>
> It depends. If you _allocate_ (e.g. ints are not allocated) a caml
> value \x13v1 then another caml v2 and then modify v1, you need to keep a
> hand on v1 with CAMLparam because it may move when you allocate v2. If
> you allocate only a single value then there is no need to do it
> (unless some code you call may invoke the gc before you use v1).
That means that I will have to review carefully my code...
>
>> Can use them without CAMLparam and CAMLreturn macros?
>
> No. But I never did the C -> ocaml -> C way so I don't really know how
> to proceed. The first thing that comes to mind is to store the result
> in a variable given to  the function.
Yes. That's the solution I was planning.
It took me a long time to narrow the problem, because I have a lot of
calls of this kind and was never bitten by this problem.
But at first glance, i did not find one in my libraries with would have
returned a small float value.

The problem is not the solution, but the fact that I will have to review
my code to check all this.

>
>
> Maybe there's another way, I don't know.
At the first place, except the fact that I misused the macros, I still
do not understand why CAMLreturn(0.05) would return 0.?

Thanks for your replies.


Matt


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [Caml-list] CAMLreturn does not work for floats between 0 and 1 ?
  2007-02-16 19:19       ` Matthieu Dubuget
@ 2007-02-16 22:28         ` Daniel Bünzli
  0 siblings, 0 replies; 8+ messages in thread
From: Daniel Bünzli @ 2007-02-16 22:28 UTC (permalink / raw)
  To: matthieu.dubuget; +Cc: Caml List


Le 16 févr. 07 à 20:19, Matthieu Dubuget a écrit :

> At the first place, except the fact that I misused the macros, I still
> do not understand why CAMLreturn(0.05) would return 0.?

Because CAMLreturn assumes its parameter is a value of the C type  
'value' which represent a value of the ocaml runtime system and can  
be either (from the doc) :

> an unboxed integer;
> a pointer to a block inside the heap (such as the blocks allocated  
> through one of the caml_alloc_* functions below);
> a pointer to an object outside the heap (e.g., a pointer to a block  
> allocated by malloc, or to a C variable).

Its something the caml runtime wants not your C code. On a 32 bit  
platform the type 'value' is a 32 bit integer so when your return  
your double with CAMLreturn it is cast to a 32 bit integer [1] and  
then after that cast again to a double. Hence you lose the fractional  
part. It doesn't make sense to use CAMLreturn with anything but a  
caml value.

Best,

Daniel

[1] Have a look at the definition of CAMLreturn in <caml/memory.h>.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [Caml-list] CAMLreturn does not work for floats between 0 and 1 ?
  2007-02-16 14:46 CAMLreturn does not work for floats between 0 and 1 ? Matthieu Dubuget
  2007-02-16 15:09 ` [Caml-list] " Daniel Bünzli
@ 2007-02-17  0:30 ` Jacques Garrigue
  1 sibling, 0 replies; 8+ messages in thread
From: Jacques Garrigue @ 2007-02-17  0:30 UTC (permalink / raw)
  To: matthieu.dubuget; +Cc: caml-list

From: Matthieu Dubuget <matthieu.dubuget@laposte.net>
> 
> I'm sure I'm doing something bad. But I can't find out where?
> 
> The problem is that when I CAMLreturn float : r with   0. < r < 1.,
> I get 0.00000000.
> 
> double f (int i){
>   CAMLparam0 ();
>   double r; 
>   static value *cr = NULL;
>   if (cr == NULL) cr = caml_named_value("f");
>   r = Double_val(caml_callback(*cr, Val_int(i)));
>   printf("f: r(%d)=%.5f\n", i, r);
>   CAMLreturn(r);
> }

As pointed by others, CAMLreturn can only be used for values of type
"value" (i.e. long int).
In this specific case, you need register no root with the GC, so there
is no point in using CAMLparam0/CAMLreturn.

If you need to register roots with the GC in such a function
(because you're calling two caml callbacks with an allocation in
between, for instance) then you must use different macros.
In 3.10, there is a new macro CAMLreturnT for this kind of
situations.
Before that, you can also use the older interface Begin_roots/End_roots.

   value v1 = 0, v2 = 0; // v1 and v2 must be initialized
   Begin_roots2(v1, v2);
   ... v1 and v2 are registered ...
   End_roots(); // pop v1 and v2
   return r;

Jacques Garrigue


^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2007-02-17  0:30 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-02-16 14:46 CAMLreturn does not work for floats between 0 and 1 ? Matthieu Dubuget
2007-02-16 15:09 ` [Caml-list] " Daniel Bünzli
2007-02-16 16:20   ` Matthieu Dubuget
2007-02-16 17:02     ` Mathias Kende
2007-02-16 17:07     ` Daniel Bünzli
2007-02-16 19:19       ` Matthieu Dubuget
2007-02-16 22:28         ` Daniel Bünzli
2007-02-17  0:30 ` Jacques Garrigue

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).