I knocked the bastard off: extern "C" { struct __gmp_alloc_cstring_c { void (*free_func) (void *, size_t); }; }
struct __gmp_alloc_cstring : __gmp_alloc_cstring_c { char *str; __gmp_alloc_cstring(char *s) { str = s; } ~__gmp_alloc_cstring() { mp_get_memory_functions (NULL, NULL, &free_func); (*free_func) (str, std::strlen(str)+1); } }; Basically I declare a C struct which makes the function pointer a pointer to a C function. Then I inherit that C struct in the C++ struct. MPIR now builds and passes make check with --enable-cxx with the Sun CC compiler. Technically the Sun compiler is correct to complain. Let's hope it still compiles with GCC! Bill. 2009/1/10 Bill Hart <goodwillh...@googlemail.com>: > 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 -~----------~----~----~----~------~----~------~--~---