I wrote a function calculating the gcd of two numbers which uses std::swap in the case where the second parameter is greater than the first.
Some time later, I realised that std::swap is not constexpr, but my function still compiled and ran successfully.
I tried with MinGW-w64 8.1.0 and Visual C++ 2017 and it worked for both.
My first thought was that's because constexpr functions are allowed to be executed at runtime, so I tried std::integral_constant<int,gcd(32,12)>, and it worked.
However, I cannot use any of my own non-constexpr function (which is what I expect).
Here is my test code :
#include <utility>
inline void foo() noexcept {
}
template<typename T>
constexpr T gcd(T a, T b) {
    // foo();            // only works with non-constexpr j
    if(a<b) {
        std::swap(a, b); // works for both constexpr i and non-constexpr j
    }
    if(b==0) {
        return a;
    } else {
        return gcd(b, a%b);
    }
}
int main()
{
    constexpr int i = std::integral_constant<int, gcd(32, 12)>::value;
    int j = gcd(32,12);
}
So, my question is : why can I use std::swap in my function ?
 
     
    