When I include the algorithm library before defining epsilon, the following code compiles:
#include <iostream>
#include <algorithm>
#define epsilon 0.00001
int main() {
std::cout << epsilon;
return 0;
}
When I switch them around, it doesn't:
#include <iostream>
#define epsilon 0.00001
#include <algorithm>
int main() {
std::cout << epsilon;
return 0;
}
It gives the following error 19 times:
epsilon_algorithm.cpp:3:17: error: expected unqualified-id before numeric constant
3 | #define epsilon 0.00001
|
On http://www.cplusplus.com/reference/algorithm/ and https://en.cppreference.com/w/cpp/algorithm there is no mention of anything named 'epsilon'. I know I can avoid the issue by simply always including <algorithm> before I define epsilon, I want to know what causes this error to broaden my understanding of C++ and prevent these types of errors in the future.
I compile with MinGW (32 bit, installed a few weeks ago) in an updated Windows 10 (64 bit) environment.
Algorithms library. The algorithms library defines functions for a variety of purposes (e.g. searching, sorting, counting, manipulating) that operate on ranges of elements. Note that a range is defined as [first, last) where last refers to the element past the last element to inspect or modify.
Parallel version of algorithms (except for std::for_each and std::for_each_n) are allowed to make arbitrary copies of elements from ranges, as long as both std::is_trivially_copy_constructible_v<T> and std::is_trivially_destructible_v<T> are true, where T is the type of elements.
The library defines a large number of specific functions to be used in various elements at a time or a range. Like any other language, C++ also has a wide range of functions in a library.
The standard library algorithms support several execution policies, and the library provides corresponding execution policy types and objects. Users may select an execution policy statically by invoking a parallel algorithm with an execution policy object of the corresponding type.
Standard library headers are allowed to include any other standard library header.
It's possible that <algorithm>
includes <limits>
and there exists std::numeric_limits::epsilon()
there. And of course macros ignore namespaces and classes, so it would try to declare a function called 0.00001
.
Don't use macros. Use C++ constants:
constexpr double epsilon = 0.00001;
And if you absolutely need macro, always define them after all includes. Defining them before makes your code very brittle - any change in those headers in the future might blow up your code with cryptic compiler errors.
Don't define macros in header files, for the same reason.
Prefer very localized macros when possible - define them where needed and #undef
after you are done. This way they won't leak to the outside (although you can still inadvertently override an existing macro).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With