C ++ gcc `floorf` не является членом` std`? - PullRequest
0 голосов
/ 11 февраля 2019

У меня есть следующий фрагмент кода:

#include <cmath>

float foo(float x, unsigned int m, float q = 0.0f)
{
    return std::floorf(x * float(m) + q);
}

Теперь, когда я пытаюсь скомпилировать это с g ++ 5.4.0 и параметрами -std=c++11, я получаю сообщение об ошибке ‘floorf’ is not a member of ‘std’.

Теперь я понимаю, что пункт 26.8 стандарта C ++ 11 требует, чтобы стандартный заголовок библиотеки C ++ <cmath> объявлял тот же набор функций, что и стандартный заголовок библиотеки C <math.h>, хотя и в пространстве имен std;и этот пункт 1.2 указывает, что «C» следует интерпретировать как C99;и этот пункт 7.12.9.2 стандарта C99 требует, чтобы стандартный заголовок библиотеки C <math.h> объявлял функцию float floorf(float).

Таким образом, по этой причине <cmath> должен объявить функцию float std::floorf(float), котораяНасколько я знаю, это должно соответствовать моему коду.

Что дает?Я что-то здесь упускаю?

(я знаю, что C ++ 11 также определяет float std::floor(float); однако недавно я обнаружил, что f -сфиксированные вариантыФункции с плавающей точкой обычно немного быстрее, поэтому я бы предпочел специально вызывать floorf().)

1 Ответ

0 голосов
/ 11 февраля 2019

Я считаю, что вы действительно нашли ошибку в шапке.На моем GCC, используя библиотеку GNU C (glibc), я могу обойтись, выпав из std:: в глобальное пространство имен, изменив

    return std::floorf(x * float(m) + q);

на

    return ::floorf(x * float(m) + q);

.Обходной путь работает, потому что floorf() принадлежит стандартной библиотеке C, поэтому у него есть глобальный символ в glibc.Поскольку для обходного пути используется глобальный символ, который C ++ 11 допускает, но не требует его существования, этот обходной путь не переносим.Тем не менее, для glibc он, похоже, работает.

Обходной путь можно сделать переносным, если вы хотите, изменив #include <cmath> на #include <math.h> и (насколько я знаю) отбросив всю вашу C-математику.-библиотечные вызовы в глобальное пространство имен.Это все равно будет просто обходной путь.

Вы можете пойти дальше и сообщить об этом как об ошибке по адресу: https://gcc.gnu.org/bugzilla/. Более того, чтобы команда GCC отнеслась к вам более серьезно, вы можете связатьотчет об ошибках здесь, чтобы показать, что несколько компетентных пар глаз уже рассмотрели проблему.А пока хорошая работа.

...