comp.lang.ada
 help / color / mirror / Atom feed
* Access to C_float wipes out float value
@ 2010-08-20  1:40 deadlyhead
  2010-08-20  2:05 ` (see below)
  2010-08-20  2:09 ` Yannick Duchêne (Hibou57)
  0 siblings, 2 replies; 4+ messages in thread
From: deadlyhead @ 2010-08-20  1:40 UTC (permalink / raw)


I'm in the unfortunate position of needing to interface to code which
deals heavily with void* c types and functions.  In order to get to
grips with this, I've written two small files whereby I created a
function which returns a void* in C, and in Ada this value is
converted to an Access type (depending on the input to the C
function), and it's .all value is then displayed.

The code:

/*************************** Begin C code ***************************/

#include "stdio.h"

void*
do_something (int get_float)
{

  int*   i;
  float* f;

  int in = 12345;
  float fl = 9876.54321;

  f = &fl;
  i = ∈

  if (!get_float) {
    printf ("Value of \"*i\" is %d\n", *i);
    return i;
  } else {
    printf ("Value of \"*f\" is %f\n", *f);
    return f;
  }
}

/**************************** End C code ****************************/

--------------------------- Begin Ada code ---------------------------

with Ada.Text_IO;         use Ada.Text_IO;

with System;
with System.Address_To_Access_Conversions;
with Interfaces.C;

procedure Void_Stuff is

   package C renames Interfaces.C;

   subtype Void_Ptr is System.Address;

   package Int_ATAC is new System.Address_To_Access_Conversions
     (Object => C.int);

   package Flt_ATAC is new System.Address_To_Access_Conversions
     (Object => C.C_float);


   package Int_IO is new Integer_IO (C.int);
   use Int_IO;

   package C_Float_IO is new Float_IO (C.C_float);
   use C_Float_IO;

   use Int_ATAC;
   use FLT_ATAC;

   type C_Bool is  (False, True);
   for  C_Bool use (False => 0, True => 1);
   pragma Convention (C, C_Bool);

   function Do_Something (Get_Float : C_Bool) return Void_Ptr;
   pragma Import (C, Do_Something, "do_something");

   My_Int : Int_ATAC.Object_Pointer;
   My_Flt : Flt_ATAC.Object_Pointer;

begin

   --  Let's do this
   My_Int := To_Pointer (Do_Something (False));

   Put ("The value of ""My_Int"" is ");
   Put (My_Int.all, Width => 0);
   New_Line;

   My_Flt := To_Pointer (Do_Something (True));
   Put ("The value of ""My_Flt"" is ");
   Put (My_Flt.all);
   New_Line;

end Void_Stuff;

---------------------------- End Ada Code ----------------------------

The output:

Value of "*i" is 12345
The value of "My_Int" is 12345
Value of "*f" is 9876.542969
The value of "My_Flt" is  6.06708E-39      <----- wtf???

I can't think of any way that I messed this up.  There must me
something about float* in C that truly screws them up when treated as
a System.Address in Ada.  I suppose that the safest way would be to
wrap such a function up in a nice, type-safe Ada function where only
one output type is possible and use an ... access Float; type instead,
but _dang_.  I really want to know what's going on here.

Maybe my problem is my dislike of C in general, and a subsequent lack
of understanding?  I plan on implementing a nice thick binding as this
project progresses, so I'll be getting around this anyway.  Thank you
if you can provide any insight, though.

-- deadlyhead



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

* Re: Access to C_float wipes out float value
  2010-08-20  1:40 Access to C_float wipes out float value deadlyhead
@ 2010-08-20  2:05 ` (see below)
  2010-08-20  2:09 ` Yannick Duchêne (Hibou57)
  1 sibling, 0 replies; 4+ messages in thread
From: (see below) @ 2010-08-20  2:05 UTC (permalink / raw)


On 20/08/2010 02:40, in article
e42a0d91-535b-4f75-8ae6-58238a51d84c@x24g2000pro.googlegroups.com,
"deadlyhead" <deadlyhead@gmail.com> wrote:

> I really want to know what's going on here.
> 
> Maybe my problem is my dislike of C in general, and a subsequent lack
> of understanding?  I plan on implementing a nice thick binding as this
> project progresses, so I'll be getting around this anyway.  Thank you
> if you can provide any insight, though.

The integer variant only work co-incidentally.

Your C function returns a pointer to a local variable which is invalidated
as soon as the function returns.

-- 
Bill Findlay
<surname><forename> chez blueyonder.co.uk





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

* Re: Access to C_float wipes out float value
  2010-08-20  1:40 Access to C_float wipes out float value deadlyhead
  2010-08-20  2:05 ` (see below)
@ 2010-08-20  2:09 ` Yannick Duchêne (Hibou57)
  2010-08-20  2:12   ` deadlyhead
  1 sibling, 1 reply; 4+ messages in thread
From: Yannick Duchêne (Hibou57) @ 2010-08-20  2:09 UTC (permalink / raw)


Le Fri, 20 Aug 2010 03:40:18 +0200, deadlyhead <deadlyhead@gmail.com> a  
écrit:
> void*
> do_something (int get_float)
> {
>
>   int*   i;
>   float* f;
>
>   int in = 12345; // <<< local
>   float fl = 9876.54321; // idem
>
>   f = &fl; // <<< reference to local
>   i = &in; // idem
>
>   if (!get_float) {
>     printf ("Value of \"*i\" is %d\n", *i);
>     return i; // <<< return reference to local
>   } else {
>     printf ("Value of \"*f\" is %f\n", *f);
>     return f; // idem
>   }
> }

Did you really want to return a reference to a local variable ? Are you  
sure ?



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

* Re: Access to C_float wipes out float value
  2010-08-20  2:09 ` Yannick Duchêne (Hibou57)
@ 2010-08-20  2:12   ` deadlyhead
  0 siblings, 0 replies; 4+ messages in thread
From: deadlyhead @ 2010-08-20  2:12 UTC (permalink / raw)


On Aug 19, 7:09 pm, Yannick Duchêne (Hibou57)
<yannick_duch...@yahoo.fr> wrote:
> Le Fri, 20 Aug 2010 03:40:18 +0200, deadlyhead <deadlyh...@gmail.com> a  
> écrit:
>
>
>
> > void*
> > do_something (int get_float)
> > {
>
> >   int*   i;
> >   float* f;
>
> >   int in = 12345; // <<< local
> >   float fl = 9876.54321; // idem
>
> >   f = &fl; // <<< reference to local
> >   i = &in; // idem
>
> >   if (!get_float) {
> >     printf ("Value of \"*i\" is %d\n", *i);
> >     return i; // <<< return reference to local
> >   } else {
> >     printf ("Value of \"*f\" is %f\n", *f);
> >     return f; // idem
> >   }
> > }
>
> Did you really want to return a reference to a local variable ? Are you  
> sure ?

Ah, thank you.  I didn't even think of that.



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

end of thread, other threads:[~2010-08-20  2:12 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-08-20  1:40 Access to C_float wipes out float value deadlyhead
2010-08-20  2:05 ` (see below)
2010-08-20  2:09 ` Yannick Duchêne (Hibou57)
2010-08-20  2:12   ` deadlyhead

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox