Constexpr doubt :/

Recommended Posts

I may have got this wrong, but I thought that stuff marked with the keyword constexpr had to be known at compile time.

Then why in my example below, where I pass to the constexpr function a value that is only know at run time, I don't get any errors?!

size_t fib(size_t n)
{
if (n <= 1)
{
return 1;
}
return fib(n - 1) + fib(n - 2);
}

constexpr size_t fib_constexpr(size_t n)
{
if (n <= 1)
{
return 1;
}
return fib(n - 1) + fib(n - 2);
}

int main()
{
int n;
cin >> n;
cout << fib(n) << endl;
cout << fib_constexpr(n) << endl;
return 0;
}

Edited by MarcusAseth

Share on other sites

Objects/values that you declare with constexpr have to be evaluated at compile time.

Functions that you declare with constexpr can be evaluated at compile time, if all their arguments are also constexpr (or other compile time constants).

It's confusing - welcome to modern C++.

Share on other sites

This language is so subtle... x_x  Thanks Kylotan

Share on other sites

Really recommend reading: Scott Meyers' "Effective Modern C++: 42 Specific Ways to Improve Your Use of C++11 and C++14", best and most interesting C++11/14 "2nd book" (i.e. the author has not the intention of teaching the basics, but rather focuses on best practices while diving straight into the content) available.

More particularly, it tackles a.o. constexpr and () vs {} initializers  .

Share on other sites

I will

I am still at Programming Principles and practice using C++ 2nd edition, around page 650 or something. Got to finish this first

Edited by MarcusAseth

Share on other sites
23 minutes ago, MarcusAseth said:

around page 650 or something

Effective Modern C++ has only 300 pages so that should be a walk in the park

Share on other sites

Declaring a function constexpr means that it is "certified" for compile-time use, to compute constants, in addition to being compiled and callable like a non-constexpr function.

In your program there is no call with constant arguments (which would be optimized away) and the two functions are basically identical. See them on Godbolt: https://godbolt.org/g/JJ4LsQ

Share on other sites

That is impossible for me to decipher, though one day learning assembly could do for an interesting hobby I think, got to keep that in mind

Create an account

Register a new account

• Forum Statistics

• Total Topics
628736
• Total Posts
2984456
• Similar Content

• By Josheir
void update() { if (thrust) { dx += cos(angle*DEGTORAD)*.02; dy += sin(angle*DEGTORAD)*.02; } else { dx*=0.99; dy*=0.99; } int maxSpeed = 15; float speed = sqrt(dx*dx+dy*dy); if (speed>maxSpeed) { dx *= maxSpeed/speed; dy *= maxSpeed/speed; } x+=dx; y+=dy; . . . } In the above code, why is maxSpeed being divided by the speed variable.  I'm stumped.

Thank you,
Josheir

• Hey there,  I have this old code im trying to compile using GCC and am running into a few issues..
im trying to figure out how to convert these functions to gcc
static __int64 MyQueryPerformanceFrequency() { static __int64 aFreq = 0; if(aFreq!=0) return aFreq; LARGE_INTEGER s1, e1, f1; __int64 s2, e2, f2; QueryPerformanceCounter(&s1); s2 = MyQueryPerformanceCounter(); Sleep(50); e2 = MyQueryPerformanceCounter(); QueryPerformanceCounter(&e1); QueryPerformanceFrequency(&f1); double aTime = (double)(e1.QuadPart - s1.QuadPart)/f1.QuadPart; f2 = (e2 - s2)/aTime; aFreq = f2; return aFreq; } void PerfTimer::GlobalStart(const char *theName) { gPerfTimerStarted = true; gPerfTotalTime = 0; gPerfTimerStartCount = 0; gPerfElapsedTime = 0; LARGE_INTEGER anInt; QueryPerformanceCounter(&anInt); gPerfResetTick = anInt.QuadPart; } /////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// void PerfTimer::GlobalStop(const char *theName) { LARGE_INTEGER anInt; QueryPerformanceCounter(&anInt); LARGE_INTEGER aFreq; QueryPerformanceFrequency(&aFreq); gPerfElapsedTime = (double)(anInt.QuadPart - gPerfResetTick)/aFreq.QuadPart*1000.0; gPerfTimerStarted = false; }
I also tried converting this function (original function is the first function below and my converted for gcc function is under that) is this correct?:
#if defined(WIN32) static __int64 MyQueryPerformanceCounter() { // LARGE_INTEGER anInt; // QueryPerformanceCounter(&anInt); // return anInt.QuadPart; #if defined(WIN32) unsigned long x,y; _asm { rdtsc mov x, eax mov y, edx } __int64 result = y; result<<=32; result|=x; return result; } #else static __int64 MyQueryPerformanceCounter() { struct timeval t1, t2; double elapsedTime; // start timer gettimeofday(&t1, NULL); Sleep(50); // stop timer gettimeofday(&t2, NULL); // compute and print the elapsed time in millisec elapsedTime = (t2.tv_sec - t1.tv_sec) * 1000.0; // sec to ms elapsedTime += (t2.tv_usec - t1.tv_usec) / 1000.0; // us to ms return elapsedTime; } #endif Any help would be appreciated, Thank you!

• Hi, I'm building a game engine using DirectX11 in c++.
I need a basic physics engine to handle collisions and motion, and no time to write my own.
What is the easiest solution for this? Bullet and PhysX both seem too complicated and would still require writing my own wrapper classes, it seems.
I found this thing called PAL - physics abstraction layer that can support bullet, physx, etc, but it's so old and no info on how to download or install it.
The simpler the better. Please let me know, thanks!

• It comes that time again when I try and get my PC build working on Android via Android Studio. All was going swimmingly, it ran in the emulator fine, but on my first actual test device (Google Nexus 7 2012 tablet (32 bit ARM Cortex-A9, ARM v7A architecture)) I was getting a 'SIGBUS illegal alignment' crash.
My little research has indicated that while x86 is fine with loading 16 / 32 / 64 bit values from any byte address in memory, the earlier ARM chips may need data to be aligned to the data size. This isn't a massive problem, and I see the reason for it (probably faster, like SIMD aligned loads, and simpler for the CPU). I probably have quite a few of these, particular in my own byte packed file formats. I can adjust the exporter / formats so that they are using the required alignment.
Just to confirm, if anyone knows this, is it all 16 / 32 / 64 bit accesses that need to be data size aligned on early android devices? Or e.g. just 64 bit size access?
And is there any easy way to get the compiler to spit out some kind of useful information as to the alignment of each member of a struct / class, so I can quickly pin down the culprits?
The ARM docs (http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.faqs/ka15414.html) suggest another alternative is using a __packed qualifier. Anyone used this, is this practical?
• By Josheir
In the following code:

Point p = a[1]; center of rotation for (int i = 0; I<4; i++) { int x = a[i].x - p.x; int y = a[i].y - p.y; a[i].x = y + p.x; a[i].y = - x + p.y; }
I am understanding that a 90 degree shift results in a change like:
xNew = -y
yNew = x

Could someone please explain how the two additions and subtractions of the p.x and p.y works?

Thank you,
Josheir

• 9
• 25
• 11
• 10
• 16