Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

gcc strange behaviour on abs function

Tags:

c++

gcc

I ported some code from windows (vs2010) to gcc

a piece of it looks like:

double r1 /* = some value */;
double r2 /* = some value */;
double diff = abs(r1-r2);
std::cerr<<  r1 << ", " << r2 << ", " << diff<< std::endl;

it compiles on gcc (arm-linux-gnueabihf-g++ (Raspbian 6.3.0-18+rpi1+deb9u1) 6.3.0 20170516) with -Wall -Wextra without warnings.

The result is:

0.121, 0.0709839, 0
0.015, 0.131958, 0
0.015, 0.00799561, 0
0.21, 0.00799561, 0
0.182, 0.205994, 0
0.015, 0.00799561, 0

On windows the result is correct. There are double-overloads on the abs functions.

I am not using namespace std;. It seems that under gcc these overloads does not exist in global namespace.

I do not know what exactly the standard says, but i would have expected at least a warning about the double->int-conversion on passing the the difference to the abs function.

Do i have something missed? Why do i not get this warning?

like image 307
vlad_tepesch Avatar asked Dec 20 '18 15:12

vlad_tepesch


2 Answers

abs is a C function that takes one integer and returns another integer.

You want to use the C++ version std::abs instead. Clang would actually warn about the mistake (I even turn it into an error -Werror=absolute-value), not sure if there is a similar flag for gcc (not warning about all conversions, just for abs).

like image 142
Matthieu Brucher Avatar answered Nov 12 '22 21:11

Matthieu Brucher


I think you are looking for the compiler option -Wfloat-conversion or, more general, -Wconversion. Then g++ gives me this warning:

 warning: conversion to ‘int’ from ‘double’ may alter its value [-Wfloat-conversion]
     double diff = abs(r1-r2);

None of the two options is included in -Wall or -Wextra.

It works as long as the conversion is in your code, see here.

like image 37
Pates Avatar answered Nov 12 '22 22:11

Pates