zell
zell

Reputation: 10204

GCC Undefined Behavior Sanitizer seems to think inf/inf is not undefined behavior. Why?

I thought inf/inf is considered undefined, as in this example below:

#include <math.h>
#include <stdio.h>
double square(double x){return x*x;}

int main(){
  double x = 2.9e200;
  printf ("x*x=%g\n", square(x)/square(x));
  return 0;
}

However, the undefined behavior sanitizer does not see this as an undefined behavior. Where do I misunderstand?

 % gcc -fsanitize=undefined hello.c && ./a.out
x*x=nan

Upvotes: 0

Views: 113

Answers (2)

supercat
supercat

Reputation: 81217

When part of the Standard characterizes something as Undefined Behavior, that means that as far as the Standard is concerned, implementations are generally free to define it or not as they see fit, presumably choosing whatever course of action would best serve their customers. In the case of floating-point math, however, the Standard adds an additional requirement: all implementations which fail to treat certain floating-point operations as defined must refrain from pre-defining a macro __STDC_IEC_559__. If an implementation pre-defines that macro, then it must treat as defined various operations that would not need to be defined on implementations that do not pre-define that macro.

Arguably, an undefined-behavior sanitizer should check whether a piece of code would only be executed on implementations that define __STDC_IEC_559__, and treat the aforementioned floating-point operations as defined only if they wouldn't occur on implementations that don't define that macro. The only practical way of doing that, however, would be to build the program twice--once with the macro defined and once without--and validate the behavior of the two machine-code programs separately.

Upvotes: 1

KamilCuk
KamilCuk

Reputation: 141493

I thought inf/inf is considered undefined

You are using gcc most probably on a sane platform - your compiler is following IEEE 754 the de-facto-standard floating point number format (also see C11 Annex F). From this pdf of that standard we can read on page 37:

7.2 Invalid operation

For operations producing results in floating-point format, the default result of an operation that signals the invalid operation exception shall be a quiet NaN that should provide some diagnostic information (see 6.2). These operations are:

[....]

e) division: division(0, 0) or division(∞, ∞)

The behavior is defined - it should be a quiet NaN.

The -fsanitize=undefined does not check for such cases, I think documentation lists what is detected.

Upvotes: 1

Related Questions