Is there a GCC warning for using symbols from the C library not through namespace std?

Viewed 707

Consider the following (buggy) C++ code:

#include <cmath>
#include <cstdlib>

#include <iostream>

int main() {
    if (abs(-0.75) != 0.75) {
        std::cout << "Math is broken!\n";
        return 1;
    } else {
        return 0;
    }
}

This code is buggy because it calls abs (meaning ::abs) instead of std::abs. Depending on the implementation, ::abs might not exist, or it might be the C abs, or it might be an overload set including a version for double, like std::abs is.

With Clang on Linux, at least in my environment, it turns out to be the second option: C abs. This provokes two warnings, even without explicitly enabling any:

<source>:7:9: warning: using integer absolute value function 'abs' when argument is of floating point type [-Wabsolute-value]
    if (abs(-0.75) != 0.75) {
        ^
<source>:7:9: note: use function 'std::abs' instead
    if (abs(-0.75) != 0.75) {
        ^~~
        std::abs
<source>:7:13: warning: implicit conversion from 'double' to 'int' changes value from -0.75 to 0 [-Wliteral-conversion]
    if (abs(-0.75) != 0.75) {
        ~~~ ^~~~~

On GCC, I get different results in different environments and I haven’t yet figured out what details of the environment are relevant. The more common option, though, is also that it calls the C abs function. However, even with -Wall -Wextra -pedantic, it gives no warnings. I can force a warning with -Wfloat-conversion, but that gives too many false positives on the rest of my codebase (which perhaps I should fix, but that’s a different issue):

<source>: In function 'int main()':
<source>:7:18: warning: conversion to 'int' alters 'double' constant value [-Wfloat-conversion]
     if (abs(-0.75) != 0.75) {
                  ^

Is there a way to get a warning whenever I use a library function through the global namespace, when the version in namespace std is an overload?

3 Answers
Related