C2027
Visual C++ Programming Language
Severity: MinorWhat Does This Error Mean?
C2027 means you tried to use a class or struct in a way that requires knowing its full layout — such as creating an instance, calling a member, or taking sizeof — but only a forward declaration was available at that point. A forward declaration (class Foo;) tells the compiler the type exists but not how big it is or what members it has. The fix is to include the header that contains the full class definition before the line that triggers C2027.
Affected Models
- Visual Studio 2015–2022
- MSVC v14.x / v17.x
Common Causes
- A header uses a forward declaration for compile-time efficiency and the .cpp file forgot to include the full header
- Circular includes were broken by replacing an include with a forward declaration in the wrong place
- Dereferencing a pointer to a forward-declared type
- Calling a member function on a forward-declared type
- Taking sizeof of a forward-declared type
How to Fix It
-
Add the full include for the missing type at the top of the file where C2027 fires. Replace or supplement the forward declaration with the actual header.
Forward declarations are fine for pointers and references — the compiler does not need the full type for those. For anything else (creating objects, accessing members, sizeof), the full header is required.
-
Check for circular include problems. If including the full header causes a circular dependency, restructure by moving the definition to a separate header or using the PIMPL pattern.
Circular includes are the most common reason people switch to forward declarations. The PIMPL (pointer to implementation) idiom breaks cycles cleanly without sacrificing full type knowledge in the .cpp file.
-
Verify the include order. The full definition must appear before the code that uses the type, not after.
Header guards and #pragma once prevent a header from being included twice, but they do not reorder includes. If header A uses type B, header A must include B's header (or the .cpp must include B before A).
Frequently Asked Questions
Why can I use a pointer to an undefined type but not an instance?
A pointer is always the same size regardless of what it points to — the compiler does not need to know the full type to allocate space for a pointer. An instance requires knowing the full size and layout to allocate and copy the object. This is why forward declarations work for pointer members in headers.