J
John Smith
I've been playing with splint, which returns the following
warning for the code below:
statlib.c: (in function log_norm_pdf)
statlib.c(1054,31): Expression has undefined behavior (left
operand uses errno,
modified by right operand): (log(x) - mu) * (log(x) - mu)
Code has unspecified behavior. Order of evaluation of function
parameters or
subexpressions is not defined, so if a value is used and
modified in
different places not separated by a sequence point
constraining evaluation
order, then the result of the expression is unspecified.
How can the offending expression be written so that the order of
evaluation is properly specified? Can t2num be assigned the value
of any single expression equivalent to ((log(x)-mu) ^ 2) * -1.0?
/* Return log normal probability density at x.
mu=a_mean(ln(X)); sigma=s_stdev(ln(X)) (output OK) */
double log_norm_pdf(double x, double mu, double sigma)
{
double t1, t2num, t2den;
if(x <= 0.0) return 0.0;
t1 = 1.0 / (sqrt(2.0 * PI) * sigma * x);
t2num = -((log(x) - mu) * (log(x) - mu)); /* problem here */
t2den = (2.0 * (sigma * sigma));
return t1 * exp(t2num / t2den);
}
BTW: this function has been rigorously tested.
warning for the code below:
statlib.c: (in function log_norm_pdf)
statlib.c(1054,31): Expression has undefined behavior (left
operand uses errno,
modified by right operand): (log(x) - mu) * (log(x) - mu)
Code has unspecified behavior. Order of evaluation of function
parameters or
subexpressions is not defined, so if a value is used and
modified in
different places not separated by a sequence point
constraining evaluation
order, then the result of the expression is unspecified.
How can the offending expression be written so that the order of
evaluation is properly specified? Can t2num be assigned the value
of any single expression equivalent to ((log(x)-mu) ^ 2) * -1.0?
/* Return log normal probability density at x.
mu=a_mean(ln(X)); sigma=s_stdev(ln(X)) (output OK) */
double log_norm_pdf(double x, double mu, double sigma)
{
double t1, t2num, t2den;
if(x <= 0.0) return 0.0;
t1 = 1.0 / (sqrt(2.0 * PI) * sigma * x);
t2num = -((log(x) - mu) * (log(x) - mu)); /* problem here */
t2den = (2.0 * (sigma * sigma));
return t1 * exp(t2num / t2den);
}
BTW: this function has been rigorously tested.