I'd like to add that constexpr in C++11/14 are evaluated at compile time and the compiler will usually replace that variable with the literal of the constexpr.
Writing:
Code: Select all
constexpr int num = 8;
constexpr int num2 = 16;
constexpr int result = num + num2;
The compiler would just do the calculations during compilation and anytime you used 'result' the compiler would replace it with the number 24 so no memory stored and no runtime calculations done. I use this when working with PI.
constexpr float pi = 3.141592f;
constexpr float radian = pi / 180.f;
constexpr float degree = 180.f / pi;
Now to convert degrees to radians, I just multiply the angle in degrees by radian before passing to the sin/cos functions.
You can also have a constexpr array, and I'm pretty sure it gets stuck in the static read-only memory as cyboryxmen says.
Code: Select all
constexpr float n1 = farray[ 0 ];
constexpr float n2 = farray[ 1 ];
constexpr float n3 = farray[ 2 ];
constexpr float n4 = farray[ 3 ];
constexpr float n5 = farray[ 4 ];
constexpr float n6 = pi;
constexpr float n7 = radian;
constexpr float n8 = degree;
PrintNumber( n1 );
PrintNumber( n2 );
PrintNumber( n3 );
PrintNumber( n4 );
PrintNumber( n5 );
PrintNumber( n6 );
PrintNumber( n7 );
PrintNumber( n8 );
Here's a snippet from the debugger:
Code: Select all
constexpr float n1 = farray[ 0 ];
constexpr float n2 = farray[ 1 ];
constexpr float n3 = farray[ 2 ];
constexpr float n4 = farray[ 3 ];
constexpr float n5 = farray[ 4 ];
constexpr float n6 = pi;
constexpr float n7 = radian;
constexpr float n8 = degree;
PrintNumber( n1 );
00007FF7ADC711B7 call PrintNumber (07FF7ADC71100h)
PrintNumber( n2 );
00007FF7ADC711BC movss xmm0,dword ptr [__real@3ec90fd8 (07FF7ADC73380h)]
PrintNumber( n2 );
00007FF7ADC711C4 call PrintNumber (07FF7ADC71100h)
PrintNumber( n3 );
00007FF7ADC711C9 movss xmm0,dword ptr [__real@3f490fd8 (07FF7ADC73384h)]
00007FF7ADC711D1 call PrintNumber (07FF7ADC71100h)
PrintNumber( n4 );
00007FF7ADC711D6 movss xmm0,dword ptr [__real@3f96cbe2 (07FF7ADC73388h)]
00007FF7ADC711DE call PrintNumber (07FF7ADC71100h)
PrintNumber( n5 );
00007FF7ADC711E3 movss xmm0,dword ptr [__real@3fc90fd8 (07FF7ADC7338Ch)]
00007FF7ADC711EB call PrintNumber (07FF7ADC71100h)
PrintNumber( n6 );
00007FF7ADC711F0 movss xmm0,dword ptr [__real@40490fd8 (07FF7ADC73390h)]
00007FF7ADC711F8 call PrintNumber (07FF7ADC71100h)
PrintNumber( n7 );
00007FF7ADC711FD movss xmm0,dword ptr [__real@3c8efa33 (07FF7ADC7337Ch)]
00007FF7ADC71205 call PrintNumber (07FF7ADC71100h)
PrintNumber( n8 );
00007FF7ADC7120A movss xmm0,dword ptr [__real@42652ee4 (07FF7ADC73394h)]
00007FF7ADC71212 call PrintNumber (07FF7ADC71100h)
Everywhere you see __real@ and some hex number, it's the floating point number, the hex number in parentheses is the address of that number. If I were to use ints instead of floats, I'm sure it would look different. The compiler is using SSE registers, so the constexpr values are being copied to those registers then sent to my PrintNumber.
By default in VS the first four floats are passed using SSE registers after that it depends on if you compile in x86 or x64, but generally they do get stored/passed using the stack.
Here's a constexpr int array
Code: Select all
constexpr int iarray[] =
{
1, 3, 5, 7, 11, 13, 17
};
And here's the debugger info
Code: Select all
PrintNumber( iarray[ 0 ] );
00007FF7A0871187 mov ecx,1
00007FF7A087118C call PrintNumber<int> (07FF7A0871FB0h)
PrintNumber( iarray[ 1 ] );
00007FF7A0871191 mov ecx,3
PrintNumber( iarray[ 1 ] );
00007FF7A0871196 call PrintNumber<int> (07FF7A0871FB0h)
PrintNumber( iarray[ 2 ] );
00007FF7A087119B mov ecx,5
00007FF7A08711A0 call PrintNumber<int> (07FF7A0871FB0h)
PrintNumber( iarray[ 3 ] );
00007FF7A08711A5 mov ecx,7
00007FF7A08711AA call PrintNumber<int> (07FF7A0871FB0h)
PrintNumber( iarray[ 4 ] );
00007FF7A08711AF mov ecx,0Bh
00007FF7A08711B4 call PrintNumber<int> (07FF7A0871FB0h)
PrintNumber( iarray[ 5 ] );
00007FF7A08711B9 mov ecx,0Dh
00007FF7A08711BE call PrintNumber<int> (07FF7A0871FB0h)
PrintNumber( iarray[ 6 ] );
00007FF7A08711C3 mov ecx,11h
00007FF7A08711C8 call PrintNumber<int> (07FF7A0871FB0h)
As you can see, accessing the elements of the constexpr int array, just replaced the variable with the actual number in the array at that index.
If you think paging some data from disk into RAM is slow, try paging it into a simian cerebrum over a pair of optical nerves. - gameprogrammingpatterns.com