Unfortunately that doesn't seem to change the interface of freefunc.
The problem seems to be that you can only change the interface of
functions at file level, and freefunc is not at file level. But
putting it at file level would make it unthreadsafe.

Bill.

2009/1/10 user923005 <dcor...@connx.com>:
>
> On Jan 9, 8:47 pm, Bill Hart <goodwillh...@googlemail.com> wrote:
>> I've been working on getting MPIR to compile on Sun CC with --enable-
>> cxx. I've fixed the attribute errors by only defining ATTRIBUTE_* when
>> __GNUC__ is defined. This fixes lots of build warnings actually,
>> though if __GNUC__ is not defined for a compiler which supports
>> attributes, then MPIR could potentially be slightly slower (probably
>> infinitesimally).
>>
>> But I'm stuck with the following:
>>
>> /* this is much the same as gmp_allocated_string in gmp-impl.h
>>    since gmp-impl.h is not publicly available, I redefine it here
>>    I use a different name to avoid possible clashes */
>> struct __gmp_alloc_cstring
>> {
>>   char *str;
>>   __gmp_alloc_cstring(char *s) { str = s; }
>>   ~__gmp_alloc_cstring()
>>   {
>>     void (*freefunc) (void *, size_t);
>>     mp_get_memory_functions (NULL, NULL, &freefunc);
>>     (*freefunc) (str, std::strlen(str)+1);
>>   }
>>
>> };
>>
>> The Sun CC compiler says:
>>
>> "../../gmpxx.h", line 1303: Error: Formal argument 3 of type extern
>> "C" void(*)(void*,unsigned long)* in call to __gmp_get_memory_functions
>> (extern "C" void*(*)(unsigned long)*, extern "C" void*(*)
>> (void*,unsigned long,unsigned long)*, extern "C" void(*)
>> (void*,unsigned long)*) is being passed void(*)(void*,unsigned long)*.
>> "../../gmpxx.h", line 1304: Warning: The variable freefunc has not yet
>> been assigned a value.
>>
>> It took me a while to figure out what the code is trying to do.
>> Basically __gmp_free_func is the default function for freeing memory
>> allocated by GMP internally. But the user can actually define their
>> own memory management functions if they want. There's an interface for
>> that, and GMP stores function pointers for the memory managment
>> functions the user specifies.
>>
>> Now if you want to free space allocated by the current memory
>> management function, then you better not call __gmp_free_func, as the
>> user may have replaced it as the current memory management function.
>> Instead you want to call the function the user defined for this
>> purpose. So you need to retrieve the function pointer GMP has stored
>> for this user defined deallocation function.
>>
>> That's what the function mp_get_memory_functions does. If you pass it
>> a reference to a function pointer as the third argument, it will set
>> that function pointer to point to the user defined deallocation
>> function.
>>
>> So in the destructor for this struct, it first declares a function
>> pointer, called freefunc. Then it calls mp_get_memory_functions with a
>> reference to freefunc as its third argument, and this sets that
>> function pointer to be the user defined allocation function. Then it
>> actually calls this deallocation function to deallocate the space
>> allocated by the initialiser for the struct.
>>
>> Now the problem is, for some stupid reason, the sun CC thinks
>> mp_get_memory_functions doesn't take a reference to a function
>> pointer, but a reference to an extern "C" function pointer. I've no
>> idea where it gets that from. The function mp_get_memory_functions is
>> defines in mp_get_gns.c and its prototype is actually:
>>
>> void
>> mp_get_memory_functions (void *(**alloc_func) (size_t),
>>                          void *(**realloc_func) (void *, size_t, size_t),
>>                          void (**free_func) (void *, size_t))
>>
>> Does anyone see how to fix this problem?
>>
>> I'm stumped.
>
> Have you tried putting
>
> #ifdef __cplusplus
> extern "C" {
> #endif
> /*
> Code goes here...
> */
> #ifdef __cplusplus
> }
> #endif
>
> Around both the declarations in the header file and also around the C
> code?
>
> I am only guessing, but a problem can arise if only one set has extern
> "C" changing the interface.
>
> To be really sure I would have to examine the code carefully.
>
> For example, consider:
>
> /* someheader.h: */
> #ifdef __cplusplus
> extern "C" double myfunc(double);
> #endif
>
> ...
>
> /* somefile.c: */
> #include "someheader.h"
> double myfunc(double d)
> {
>  return sin(d) * sqrt(d);
> }
>
> Now, since the function definition is not actually bracketed with
> extern "C" like the declaration is, then the implementation file will
> have a name mangled object and we won't find it if we reference it
> using the header file.
>
>
> >
>

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"mpir-devel" group.
To post to this group, send email to mpir-devel@googlegroups.com
To unsubscribe from this group, send email to 
mpir-devel+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/mpir-devel?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to