Don't top post, that's rude.
The function is as following
OK, I'll first discuss the particulars of that function, then
show how you can achieve a dump of a float value.
***********************
const char *dump_float(
const float &real // reference to float to be output
)
Make the return value a std::string.
You're returning a pointer to a global or perhaps a member
character array.
It's very evil.
// PUBLIC FUNCTION: dump_float() - format a float for dump.
// This function returns a pointer to a 0-terminated character
// vector containing the value of the float "real" formatted for
// use in an object dump. It handles the case(s) in which the data
// does not have a valid floating point representation. Such a
// situation can arise when a union field of more than one data type
// is interpreted as a float.
Don't use unions, they're evil.
Instead, use C++ virtual functions and inheritance.
See the C++ FAQ.
{
// save the float in a global so that the signal handler can output
// the value if signal occurs.
u_val.p_val = *((void**)(&real));
Now _that_ is unbelievably evil. How does the signal handler
(note that a signal handler is also evil in C++) know that this
void* pointer is a float*? And if it must always be, why not
use a float*?
Btw., globals like u_val are evil.
// GNU strstream ctor does not take a mode
#ifdef __GNUC__
strstream out(ptr_buf, buf_size);
#else
strstream out(ptr_buf, buf_size, ios:
ut);
#endif
Use std::stringstream.
Globals like out_p are evil.
Use local variables, not globals.
// set up the handler for the SIGFPE signal (if appropriate)
sig_handle_func_p prev_sigfpe_val = (sig_handle_func_p) signal(SIGFPE,
SIG_IGN);
You do not show the definition of sig_handle_func_p, but the cast
indicates that it's an incorrect definition.
if (prev_sigfpe_val != (sig_handle_func_p)SIG_IGN) {
// install own signal handler
signal(SIGFPE, sigfpe_handler);
This is probably where the compiler says "enough". You do not show
your definition of sigfpe_handler. But judging from the compiler's
error message it's something like
void f( int x ) { ... }
which is incorrect.
}
// dump the floating point representation of the scalar value
if (setjmp(sjbuf) == 0) {
sprintf(pbuf, "%-15g", (double)real);
The use of sprintf is inconsistent with the use of strstream.
At your current level, use std::stringstr.
Here you simply ignore the case of a signal occurring, and
proceed to return a pointer to an uninitialized buffer. That
is a bug.
if (prev_sigfpe_val != (sig_handle_func_p)SIG_IGN) {
// restore the original action in the event of the SIGFPE signal.
signal(SIGFPE, prev_sigfpe_val);
}
return ptr_buf;
}
*********************************************
It is compiled with the forte 6 Solaries compiler, and the error is: Error:
Could not find a macth for std::signal(int, void(*)(int))
Okay, what you're trying to achieve seems to be to convert a
float value to decimal representation, if and only if it is a
valid float value.
The conversion part is easily accomplished in C++, and I suggest
you write that as a simple function that _assumes_ (has as
precondition) that the float value is valid. std::stringstr
handles the cases of IEEE Inf and so on. The function declaration
would be something like
std::string toString( float aFloat )
{
// stuff here using std::strstream
}
The if and only if valid part is not easily accomplished in C++,
since C++ allows the compiler to choose the representation of
float and double. Here I suggest that you restrict your program
to compilers that support IEEE standard format. You can check
whether a particular compiler does via std::numeric_limits.
Hth.,
- Alf