1

I did a static_assert to make sure that a valid type was used. I don't know if I just should have checked if the type is void, or whether any type can have size zero (I think it can with [[no_unique_address]]), but it was the warning message that was interesting:

template <typename T> class MyClass { public: static_assert(sizeof (T) > 0); }; 

Clang-Tidy:

Suspicious comparison of 'sizeof(expr)' to a constant

If I do this, the warning goes away:

static_assert(sizeof T > 0); 

What does the warning mean, and why does it go away when I take away the parentheses?

6
  • 2
    sizeof T just isn't valid for a type T. My guess is that clang-tidy doesn't have a specific warning for that, but that you will instead get an error when compiling it properly: "error : expected parentheses around type name in sizeof expression" Commented Jun 6 at 8:04
  • 2
    [[no_unique_address]] doesn't change the size of an object. It makes it possible for an instance of an empty class (which has at least the size 1) to share the address with another member variable. Commented Jun 6 at 8:09
  • @TedLyngmo Umm, doesn't that make it zero size? Oh you mean it's zero size in the context of its parent class, but if you do sizeof(that_class) it returns 1? Commented Jun 6 at 8:31
  • @Zebrafish "it's zero size in the context of its parent class" - I guess that's one way of putting it. It has the same size as without [[no_unique_address]] but it may affect the size of the parent. class MyClass { char dummy; [[no_unique_address]] EmptyClass foo; }; - here MyClass will probably have size 1, not 2. Commented Jun 6 at 8:37
  • @Bop But why does it expect parentheses? sizeof is an operator, not a function. It doesn't need parentheses. sizeof char is perfectly legal, for example. Commented Jun 7 at 2:22

1 Answer 1

6

The warnings generated by clang tidy related to sizeof are documented here. Specifically:

WarnOnSizeOfCompareToConstant

When true, the check will warn on an expression like sizeof(expr) <= k for a suspicious constant k while k is 0 or greater than 0x8000. Default is true.

It warns because sizeof(T) cannot be 0.

It does not warn for static_assert(sizeof T > 0) because that's an error:

<source>:6:25: error: expected parentheses around type name in sizeof expression 6 | static_assert(sizeof T > 0); | ^ | ( ) 
Sign up to request clarification or add additional context in comments.

5 Comments

sizeof(T) cannot be 0. OK, are you sure about that? Then I should just check against void with std::is_same_v<std::remove_cv_t<T>, void> ?
@Zebrafish yes, something that has an address occupies at least that address. As mentioned in comments above, the zero size you refer to is an excpetion for the size taken by instances of empty classes, but even then sizeof(T) wont be 0.
@Zebrafish if you want to check whether T is void you should do that. sizeof(void) isnt valid anyhow, as void is an incomplete type.
@Zebrafish I dont know the corresponging place in the standard, but cppref mentions "The result of sizeof is always nonzero, even if applied to an empty class type."

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.