John
John

Reputation: 43

static_assert in a macro but also expand to something that can be used as a function parameter

For instance. I have the macro CHARCOUNT(x) that expands to sizeof(x)/sizeof(x[0]). I would like to use static_assert to ensure each macro expansion does a check to see if the result is greater than 2 to avoid someone passing in a pointer to a string and not pointer to an array of characters.

I would like something like this static assert:

static_assert(x) > 2

This macro would be used to ensure that string copies don't exceed the buffer size such as:

TCHAR szMyStr[10];
_tcscpy_s(szMyStr, CHARCOUNT(szMyStr), L"My result");

If someone accidentally passes in a pointer where CHARCOUNT would result in the length of the pointer to the string instead of the number of bytes I would like an assert at compile time.

const TCHAR* myChars = L"My result";
auto len = CHARCOUNT(myChars);

The CHARCOUNT above should result in a compile time assert. Any pointers would be helpful.

Upvotes: 1

Views: 497

Answers (1)

Pezo
Pezo

Reputation: 1448

You should be using std::extent instead of that macro, which gives you 0 for unsupported types (e.g. arrays without bounds, non-array types).

For your use case a constexpr function that gives you the size for an array variable would be better suited, like so:

template <typename T, std::size_t N>
constexpr std::size_t arrsize(T (&)[N]) {
    return N;
}

Then you don't need to assert on the size since you can only use the function with actual arrays.

Upvotes: 7

Related Questions