This section lists frequently asked developer questions.
It’s a C++ floating-point literal for zero of type
We use literals to define constants with a specific type, in that case the zero-value.
There is also
0.0_prt, which is a literal zero of type
In std C++, you know:
We do not use use those, so that we can configure floating point precision at compile time and use different precision for fields (
amrex::Real) and particles (
You can also write things like
42.0_prt if you like to have another value than zero.
We use these C++ user literals (, , ), because we want to avoid that double operations, i.e.,
3. / 4., implicit casts, or even worse integer operations, i.e.,
3 / 4, sneak into the code base and make results wrong or slower.
Do you worry about using
int for indexing things?
std::size_t is the C++ unsigned int type for all container sizes.
Close to but not necessarily
uint, depends on the platform.
For “hot” inner loops, you want to use
int instead of an unsigned integer type. Why? Because
int has no handling for overflows (it is intentional, undefined behavior in C++), which allows compilers to vectorize easier, because they don’t need to check for an overflow every time one reaches the control/condition section of the loop.
C++20 will also add support for ssize (signed size), but we currently require C++17 for builds.
Thus, sometimes you need to
Why use this over just *my_ptr = new <class>?
Because so-called smart-pointers, such as
std::unique_ptr<T>, do delete themselves automatically when they run out of scope.
That means: no memory leaks, because you cannot forget to
delete them again.
Why name header files
.H instead of
This is just a convention that we follow through the code base, which slightly simplifies what we need to parse in our various build systems. We inherited that from AMReX. Generally speaking, C++ file endings can be arbitrary, we just keep them consistent to avoid confusion in the code base.
To be explicit and avoid confusion (with C/ObjC), we might change them all to
.cxx at some point, but for now
.cpp is what we do (as in AMReX).
#include "..._fwd.H" and
#include <...Fwd.H> files?
These are C++ forward declarations.
#include statements copy the referenced header file literally into place, which can increase the compile time of a
.cpp file to an object file significantly, especially with transitive header files including each other.
What does const int
/*i_buffer*/ mean in argument list?
This is often seen in a derived class, overwriting an interface method.
It means we do not name the parameter because we do not use it when we overwrite the interface.
But we add the name as a comment
/* ... */ so that we know what we ignored when looking at the definition of the overwritten method.