# Preprocessing CP2K uses preprocessing to either write code automatically, error handling, conditional compilation or prevention of issues with compilers. CP2K employs two different preprocessors: the traditional C-Preprocessor and [Fypp](https://github.com/aradi/fypp). ## Conditional compilation CP2K requires a separate wrapper module for every of its external dependencies. To prevent linking and compilation errors, we need to remove the respective code if CP2K is compiled without support for this dependency and introduce dummy code and `CPABORT`s to inform the user that a feature is not available. This is commonly achieved using the C-preprocessor. ```{note} This feature should not be used outside of wrapper modules to prevent fragmentation and improve maintainability. ``` ## Error handling See the [error handling](error-handling.md). ## Prevention of compiler issues Compilers, like every sufficiently large piece of software, are prone to bugs, may miss features, throw unwanted warnings/errors or have better support for performance-related extensions. We use the C-preprocessor to circumvent them. - Unused dummy arguments: Unused dummy arguments introduce unwanted overhead. That is why CP2K asks the compilers to emit warnings if such a dummy argument is found. Because the (some) dummy arguments of procedures in library wrappers are unused, we wrap them as `MARK_USED(argument)` with the `MARK_USED`-macro defined in [base_uses.F90](https://github.com/cp2k/cp2k/blob/master/src/base/base_uses.f90) to prevent the compiler from emitting warnings. ```{note} This trick does not work in the rare case of assumed-size arguments where we need the explicit `IF (.FALSE.) THEN; DO; IF (ABS(array(1)) > ABS(array(1))) EXIT; END DO; END IF` instead. ``` - Missing features or compiler bugs: Because CP2K needs to support a large variety of compilers and compiler versions, we may need to circumvent missing features or bugs of earlier versions. It is not uncommon to find them after merging a Pull Request with our extensive test suite on the Dashboard. Their fix depends on the use case. Currently relevant issues are (with macros defined in [base_uses.F90](https://github.com/cp2k/cp2k/blob/master/src/base/base_uses.f90)) - default initializers of derived types with `ALLOCATABLE` components: Check the value of `FTN_NO_DEFAULT_INIT`. If it is true, call the initializer by explicitly setting all `ALLOCATABLE` components to `NULL()` (see for instance [here](https://github.com/cp2k/cp2k/blob/master/src/mp2_types.F)), otherwise, use the ordinary default initializer. - OOP features in OpenMP regions: Instead of `DEFAULT(NONE)` at the start of a `PARALLEL` region, use `DEFAULT(OMP_DEFAULT_NONE_WITH_OOP)`. - Support for performance-related features. ## Code generation This is in principal possible with both preprocessors but CP2K relies on the capabilities of Fypp. The reason is that Fypp allows the use of Python expression to precompute expressions which may also used for a more refined preprocessing in contrast to the C-Preprocessor. Another reason is that Fypp automatically splits lines which the C-Preprocessor does not. This feature is currently used in two places: In the `xc`-module, we use it to write the code to calculate the up to 45 different but structurally similar terms of the second-order XC kernel. In the `eri_mme` package, we use it to unroll the loops of the necessary kernels and the easiest combinations of parameters.