How to combine static_assert with sizeof and stringify?

后端 未结 4 1945
忘掉有多难
忘掉有多难 2020-12-30 01:55

Memory usage is quite critical in my application. Therefore I have specific asserts that check for the memory size at compile time and give a static_assert if the size is d

相关标签:
4条回答
  • 2020-12-30 02:41

    I'd use dispatching on a function template to do the checking:

    #include <cstddef>
    
    template <typename ToCheck, std::size_t ExpectedSize, std::size_t RealSize = sizeof(ToCheck)>
    void check_size() {
      static_assert(ExpectedSize == RealSize, "Size is off!");
    }
    
    struct foo
    {
      char bla[16];
    };
    
    int main()
    {
      check_size<foo, 8>();
      return 0;
    }
    

    Results in:

    In instantiation of ‘void check_size() [with ToCheck = foo; long unsigned int ExpectedSize = 8ul; long unsigned int RealSize = 16ul]’:
    bla.cpp:15:22:   required from here
    bla.cpp:5:1: error: static assertion failed: Size is off!
    

    The debugging information is in the template parameters of the back-trace.

    If this is truly better, you will have to decide and it also depends on the compiler. It also enables you to hide the expected size with a template map, to sum up to a max size and other fancy things.

    0 讨论(0)
  • 2020-12-30 02:45

    Here's an alternative header-only solution if you can modify the struct's definition a bit and don't mind some ugliness.

    template <int RealSize = 0, int ExpectedSize = 0>
    struct _MyStruct {
        static_assert(RealSize == ExpectedSize, "size is invalid");
    
        int x;
    };
    
    typedef _MyStruct<sizeof(_MyStruct<>), 4> MyStruct;
    

    clang outputs:

    prog.cpp:4:5: error: static_assert failed "size is invalid"
        static_assert(RealSize == ExpectedSize, "size is invalid");
        ^             ~~~~~~~~~~~~~~~~~~~~~~~~
    prog.cpp:12:14: note: in instantiation of template class '_MyStruct<4, 8>' requested here
        MyStruct m;
    

    One caveat here is that the check will only occur if you instantiate the type somewhere -- just using a pointer won't trigger the error, so definitely not a great fit for all situations!

    0 讨论(0)
  • 2020-12-30 02:49

    Depending on your compiler, templates may be able to help:

    template<int s, int t> struct check_size {
      static_assert(s == t, "wrong size");
    };
    check_size<2+2, 5> doubleplusungood;
    

    gcc outputs:

    prog.cpp: In instantiation of 'check_size<4, 5>':
    prog.cpp:5:20:   instantiated from here
    prog.cpp:2:3: error: static assertion failed: "wrong size"
    
    0 讨论(0)
  • 2020-12-30 02:56

    As you discovered, the problem is here (also see this very similar question) :

    #define CHECKMEM(mytype, size)  #sizeof(mytype)
    

    It is not possible to do, because the stringification is done by the preprocessor, and sizeof is evaluated during the compilation.

    0 讨论(0)
提交回复
热议问题