Preprocessor and Build Boundaries
Constexpr Config
constexpr names a value that can be used at compile time, while ordinary variables still drive runtime decisions.
constexpr
A `constexpr` variable is known during compilation when its initializer is also a constant expression.
Constexpr Config
constexpr_config.cpp
Replay: real traced execution (multi-file project)
#include <array>
#include <iostream>
int main() {
constexpr int freeLimit = 3;
int used = 2;
std::array<int, freeLimit> included{1, 2, 3};
bool overLimit = used > freeLimit;
std::cout << "freeLimit=" << freeLimit << std::endl;
std::cout << "includedSlots=" << included.size() << std::endl;
std::cout << "used=" << used << std::endl;
std::cout << "overLimit=" << overLimit << std::endl;
return 0;
}
#include <array>
#include <iostream>
int main() {
constexpr int freeLimit = 3;
int used = 1;
std::array<int, freeLimit> included{1, 2, 3};
bool overLimit = used > freeLimit;
std::cout << "freeLimit=" << freeLimit << std::endl;
std::cout << "includedSlots=" << included.size() << std::endl;
std::cout << "used=" << used << std::endl;
std::cout << "overLimit=" << overLimit << std::endl;
return 0;
}
#include <array>
#include <iostream>
int main() {
constexpr int freeLimit = 3;
int used = 4;
std::array<int, freeLimit> included{1, 2, 3};
bool overLimit = used > freeLimit;
std::cout << "freeLimit=" << freeLimit << std::endl;
std::cout << "includedSlots=" << included.size() << std::endl;
std::cout << "used=" << used << std::endl;
std::cout << "overLimit=" << overLimit << std::endl;
return 0;
}
freeLimit ← 3, used ← 2, included ← (empty), overLimit ← 0
4int main() {5 constexpr int freeLimit→ 3 = 3;6 int used→ 2 = 2; //@used=1, 478 std::array<int, freeLimit> included→ (empty){1, 2, 3};9 bool overLimit→ 0 = used2 > freeLimit3;1011 std::cout << "freeLimit=" << freeLimit3 << std::endl;12 std::cout << "includedSlots=" << included(empty).size() << std::endl;13 std::cout << "used=" << used2 << std::endl;14 std::cout << "overLimit=" << overLimit0 << std::endl;15 return 0;16}outputfreeLimit=3 includedSlots=3 used=2 overLimit=0
freeLimit ← 3, used ← 1, included ← (empty), overLimit ← 0
4int main() {5 constexpr int freeLimit→ 3 = 3;6 int used→ 1 = 1;78 std::array<int, freeLimit> included→ (empty){1, 2, 3};9 bool overLimit→ 0 = used1 > freeLimit3;1011 std::cout << "freeLimit=" << freeLimit3 << std::endl;12 std::cout << "includedSlots=" << included(empty).size() << std::endl;13 std::cout << "used=" << used1 << std::endl;14 std::cout << "overLimit=" << overLimit0 << std::endl;15 return 0;16}outputfreeLimit=3 includedSlots=3 used=1 overLimit=0
freeLimit ← 3, used ← 4, included ← (empty), overLimit ← 1
4int main() {5 constexpr int freeLimit→ 3 = 3;6 int used→ 4 = 4;78 std::array<int, freeLimit> included→ (empty){1, 2, 3};9 bool overLimit→ 1 = used4 > freeLimit3;1011 std::cout << "freeLimit=" << freeLimit3 << std::endl;12 std::cout << "includedSlots=" << included(empty).size() << std::endl;13 std::cout << "used=" << used4 << std::endl;14 std::cout << "overLimit=" << overLimit1 << std::endl;15 return 0;16}outputfreeLimit=3 includedSlots=3 used=4 overLimit=1
Follow the Config
freeLimitis3, and the array uses that value for its size.includedhas three slots:1,2, and3.usedstarts at2.overLimitchecks whetherused > freeLimit.- With
2 > 3false, the program printsoverLimit=0. | used | freeLimit | includedSlots | overLimit output | | ---: | ---: | ---: | --- | | 1 | 3 | 3 | overLimit=0 | | 2 | 3 | 3 | overLimit=0 | | 4 | 3 | 3 | overLimit=1 |
Exercise: constexpr_config.cpp
Reproduce freeLimit=3, includedSlots=3, used=2, and overLimit=0, then use used 1 and 4 to predict the overLimit line.