Does adding a static constexpr member change the memory mapping of a struct/class?

constexpr vs const
constexpr const
c++ static class member
template constexpr
static member variable c++
c static member initialization
constexpr auto

Note: This question arised in the context of shared memory between a C++ and C# program.

In C++11, does adding a static constexpr member change anything in term of memory mapping? I would intuitively say that a static constexpr member doesn't occupy any memory, but I suppose I am ignoring some very fundamental aspect, like polymorphism for example...

So, in the following example, are an instance of Dummy and an instance of Dummy2 guaranteed to occupy the same amount of memory?

struct Dummy {
  static constexpr std::size_t kSize = 512;
  char data[kSize];

static constexpr std::size_t kSize2 = 512;
struct Dummy2 {
  char data[kSize2];

In this test this theory is not disproved, but I am very far from being able to say that this is guaranteed.

int main() {
    std::cout << sizeof(Dummy) << " " << sizeof(Dummy2) << std::endl;

512 512

Per the language standard,

9.4.2 Static data members []

  1. A static data member is not part of the subobjects of a class. If a static data member is declared thread_- local there is one copy of the member per thread. If a static data member is not declared thread_local there is one copy of the data member that is shared by all the objects of the class.

emphasis mine.

It doesn't matter whether it is constexpr or not; it's static, and as such is not part of instance composition.

const can only be used with non-static member function whereas constexpr can be used with member and non-member functions, even with constructors but with​  Note: This question arised in the context of shared memory between a C++ and C# program. In C++11, does adding a static constexpr member change anything in term of memory mapping? I would intuitively say that a static constexpr member doesn't occupy any memory, but I suppose I am ignoring some very fundamental aspect, like polymorphism for example

Dummy and Dummy2 are layout-compatible (static members don't matter), see class.mem/23.

However, the standard doesn't define what exact properties layout-compatible types have (it only defines when two types are layout-compatible, but doesn't say anything about the consequences). The intention must be that they have the same layout in memory, so you can assume that sizeof(Dummy) equals to sizeof(Dummy2).

Inside a class definition, the keyword static declares members that are not class X { static int n; }; // declaration (uses 'static') int X::n = 1; // definition (does not use 'static') struct X { static const int n = 1; static constexpr int m = 4; }; const int *​p = &X::n, Support us · Recent changes · FAQ · Offline version  Each nonstatic data member and base class subobject is initialized. Each constructor that is used for initializing nonstatic data members and base class subobjects is a constexpr constructor. Initializers for all nonstatic data members that are not named by a member initializer identifier are constant expressions.

The language definition puts a few constraints on object layout, but within those constraints, the compiler has a great deal of leeway. The language definition does not require the layout to change when you add a static member, and it doesn’t prohibit it from changing. There’s no obvious reason for changing the layout, but there is no absolute answer. It probably won’t change, but if it really matters, try it and see.

for the constructor of a class or struct, every base class sub-object and every non-​variant non-static data member must be initialized. If the class is  A constexpr specifier used in a function or static member variable (since C++17) declaration implies inline. If any declaration of a function or function template has a constexpr specifier, then every declaration must contain that specifier. A constexpr variable must satisfy the following requirements: its type must be a LiteralType.

Major changes are those that were added in the form of a dedicated paper, P0386R2, Deprecate redeclaration of static constexpr class members, Given struct X { static constexpr int n Implied for static constexpr class data members. An allocator that uses a memory resource, which can be changed at  Static member functions cannot be virtual, const, or volatile. The address of a static member function may be stored in a regular pointer to function, but not in a pointer to member function. Static data members. Static data members are not associated with any object. They exist even if no objects of the class have been defined.

If you don't want a global object to change, declare it const or constexpr . In a multi-threaded environment, the initialization of the static object does not to a pointer/reference to a base of C and the base class contains data members. struct Bar { vector<pair<int, int>> v; map<string, int> m; string s; }; Bar b; // b = b;​  A static data member of a literal type can be declared with the constexpr specifier in the class definition, and the data member declaration must specify a constant initializer. For example: struct Constants { static constexpr int bounds[] = { 42, 56 }; }; float a[Constants::bounds[0]][Constants::bounds[1]];

C++11 is a version of the standard for the programming language C++. It was approved by Significant changes were also made to the C++ Standard Library, will be invoked with an const std::vector<T>& , incurring a significant memory with C. Similarly, a class with public and private non-static data members would not  A static data member must be defined at file scope. An integral data member that you declare as const static can have an initializer. C++ needs you to define static class members somewhere, because the class symbol is global (and so is your member). This can't be done in the header because of multiple definitions.

  • A static non - constexpr doesn't change the memory mapping of a class instance. keyword there is static. So, why would making it constexpr be any different ?
  • @WhozCraig Can you refer me to a source for that? I could find this…, but I am in trouble in finding the right search terms
  • 9.4.2 [] specifically states that static data members are "not part of the subobjects of a class." So, whether constexpr or not, they should take no footprint therein. All object sizing throughout the standard make specific language to ensure "non-static" when describing everything that is anything when it comes to members and their size contribution. I doubt that is by accident.
  • 22 and 23 together give a pretty clear explanation indeed. Maybe it's worth to coopy paste them here for posterity
  • Standard layout is also relevant.
  • @Antonio: if class types are layout-compatible, then they have standard-layout already.
  • Yep, it was more a note for myself.
  • I think from geza answer static members are supposedly not allowed to change the layout.
  • @Antonio -- that's right for standard-layout classes. It's not true in general.
  • "it doesn't prohibit it from changing" is then not true in many cases: for standard-layout classes it is indeed prohibited. I think that is worth underlining, also because it matches the example that goes with the question.