The reason why constexpr static data members were made implicitly inline was to solve a common problem in C++: when defining a class-scoped constant, one was previously forced to emit the definition in exactly one translation unit, lest the variable be ODR-used:
// foo.h
struct foo {
static constexpr int kAnswer = 42;
};
// foo.cpp
// a linker error will occur if this definition is omitted before C++17
#include "foo.h"
constexpr int foo::kAnswer;
// main.cpp
#include "foo.h"
#include <vector>
int main() {
std::vector<int> bar;
bar.push_back(foo::kAnswer); // ODR-use of 42
}
In such cases, we usually care only about the value of the constant, not its address; and it's convenient for the compiler to synthesize a unique location for the constant in case it really is ODR-used, but we don't care where that location is.
Thus, C++17 changed the rules so that the out-of-line definition is no longer required. In order to do so, it makes the declaration of foo::kAnswer an inline definition, so that it can appear in multiple translation units without clashing, just like inline functions.
For namespace-scope constexpr variables (which are implicitly static, and therefore have internal linkage, unless declared extern) there is no similar issue. Each translation unit has its own copy. inline, as it's currently specified, would have no effect on such variables. And changing the existing behaviour would break existing programs.