Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can't I include the standard algorithm library after defining 'epsilon' in C++?

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.

like image 760
rvvermeulen Avatar asked Jul 15 '20 14:07

rvvermeulen


People also ask

What is Algorithms Library in C++?

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.

Can parallel algorithms make arbitrary copies of elements?

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.

What is a library in C++?

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.

How do I select an execution policy in the standard 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.


1 Answers

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).

like image 155
Yksisarvinen Avatar answered Oct 09 '22 11:10

Yksisarvinen