geometrian
geometrian

Reputation: 15387

Cannot use `static_assert` with `sizeof` inside class scope (but method scope is okay)

Here's an excerpt from a simple example (see the full source live here):

class Foo final {
    public:
        int var;

        inline Foo(void) {
            static_assert(sizeof(Foo)==sizeof(int),"Implementation error!");
        }

        static_assert(sizeof(Foo)==sizeof(int),"Implementation error!");
};

On a recent g++ (N.B. MSVC doesn't complain), this produces something like:

error: invalid application of ‘sizeof’ to incomplete type ‘Foo’

That error occurs only on the second static_assert.

I understand that the class's definition hasn't finished being written out lexically, but surely all the information for a complete type is there, right? I mean, we're inside the thing. And even if not, why would it work in the method?

Upvotes: 3

Views: 398

Answers (1)

Ben Voigt
Ben Voigt

Reputation: 283763

The class type is complete inside its own member function bodies (as Matt says, processing of the function bodies is deferred). It's not complete in most other places inside the {} of the class definition, including that static_assert. The rule from section 9.2 is

A class is considered a completely-defined object type (or complete type) at the closing } of the class-specifier. Within the class member-specification, the class is regarded as complete within function bodies, default arguments, using-declarations introducing inheriting constructors (12.9), exception-specifications, and brace-or-equal-initializers for non-static data members (including such things in nested classes). Otherwise it is regarded as incomplete within its own class member-specification.

Think about it for a minute, how should the compiler know that you don't have

int another_var;

coming right after the static_assert?

The best place for the static_assert is probably right after the class definition, in namespace scope.

Upvotes: 5

Related Questions