Nagłówek <math.h>
jest C std lib nagłówka. Definiuje wiele rzeczy w globalnej przestrzeni nazw. Nagłówek <cmath>
jest wersją C++ tego nagłówka. Definiuje zasadniczo te same rzeczy w przestrzeni nazw std
. (Są pewne różnice, na przykład wersja C++ zawiera przeciążenia niektórych funkcji, ale to nie ma znaczenia.) Nagłówek <cmath.h>
nie istnieje.
Ponieważ dostawcy nie chcą utrzymywać dwóch wersji tego samego nagłówka, wymyślili różne możliwości posiadania tylko jednego z nich za kulisami. Często jest to nagłówek C (ponieważ kompilator C++ jest w stanie to przeanalizować, podczas gdy przeciwieństwo nie działa), a nagłówek C++ po prostu obejmuje to i przeciąga wszystko do przestrzeni nazw std
. Lub istnieje trochę magii makro do parsowania tego samego nagłówka z lub bez namespace std
owiniętego wokół niego, czy nie. Do tego dodać, że w niektórych środowiskach jest to niezręczne, jeśli nagłówki nie mają rozszerzenia pliku (np. Redaktorzy nie podświetlają kodu itp.). Niektórzy dostawcy mieliby więc jeden liniowiec, w tym inny nagłówek z rozszerzeniem .h
. Lub niektóre z mapowałby wszystkie obejmuje dopasowanie <cblah>
do <blah.h>
(który, poprzez magię makro, staje się nagłówkiem C++, gdy __cplusplus
jest zdefiniowany i w przeciwnym razie staje się nagłówkiem C) lub <cblah.h>
lub cokolwiek innego.
To jest powód, dla którego na niektórych platformach, w tym na przykład <cmath.h>
, które nie powinny istnieć, początkowo się powiedzie, chociaż może sprawić, że kompilator przestanie działać spektakularnie później.
Nie mam pojęcia, z której implementacji biblioteki STD korzystasz. Przypuszczam, że to ten, który pochodzi z GCC, ale tego nie wiem, więc nie mogę wyjaśnić dokładnie, co się stało w twoim przypadku. Ale jest to z pewnością mieszanka jednego z powyższych hacków specyficznych dla danego dostawcy, w tym nagłówek, do którego nie powinieneś się zaliczać. Może to jest ta, w której <cmath>
mapuje na <cmath.h>
z konkretnym (zestawem) makr, których nie zdefiniowałeś, dzięki czemu uzyskałeś obie definicje.
Należy jednak pamiętać, że ten kod nadal nie powinien skompilować:
#include <cmath>
double f(double d)
{
return abs(d);
}
Tam nie powinno być abs()
w globalnej przestrzeni nazw (to std::abs()
). Jednak zgodnie z opisanymi powyżej sztuczkami implementacyjnymi może być. Przeniesienie takiego kodu w późniejszym czasie (lub po prostu próba skompilowania go z następną wersją Twojego dostawcy, która na to nie pozwala) może być nudne, więc powinieneś mieć to na oku.
Strona cplusplus, którą cytujesz, nie zawiera cmath.h. Mówi cmath. To jest wersja C++ dla math.h. Nie dołączaj obu. –