Inspecting Type and Value Info at C++ Compile Time
Templates can be used to smuggle out compile-time information via error messaging, and you can do this for type, size and alignment information regardless of your development environment.
Since this leverages the build tooling, this works in a variety of development environments, from VIM on a remote Linux server, to Windows with Visual Studio. It also works with types in templates, wrapped in multiple using
, stringified together with ##
, and with multiple macro layers like handle types, where IDEs can get confused.
Inspecting Types
The idea is that you generate an error which results in the error messaging being embedded in the type information for a template. This works with MSVC, Clang, and G++.
This is an incomplete type. This means when you try to make a value of that type, you get an error at compile time.
Here's a simple example:
This gives a reasonable message with the type at compile time. Even if you're deep in a change which doesn't build yet, you can still get type information for auto
variables, template types, and expressions.
What you're looking for is that response nestled as the template parameter in InspectType<...>
: unsigned long
.
When Compiler Messages are too Helpful
C++ compilers have been working on improving messages and sometimes the messages are a bit too helpful. This is possible when dealing with templates hidden behind a type alias.
std::string
is a bit more complicated than MSVC leads on here:
Clang provides a bit more info, but not the entire story as well:
Usually, this sort of shorter, more direct messaging is exactly what we want! However, when debugging sometimes we want to see the whole lot of information.
Inspection can be delayed until linking with this gadget:
This produces a spammier and more difficult to read message, but it works as a fallback when IDEs and other methods fail. What happens here is the template declares a function and because there's not one implemented, the linker will generate an error with the type information.
MSVC:
Hidden in this is our type: class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >
.
Clang:
Hidden in this is our type std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >
.
It's not a preferred way to go about getting this information, but it's available when other methods fail.
Value inspection
Using non-type template parameters, you can use incomplete types to also see compile-time values.
This allows seeing size and alignment info and prevents the need to guess, such as when setting up static_assert
s to verify type sizes or when rearranging fields to reduce padding.
With MSVC this gives the message:
And for Clang:
G++ has a similar message:
IDE support
This is a fallback method for me when IDE methods fail.
Visual Studio and CLion both report size info for me when hovering a type. Visual Studio also shows alignment and has a "Memory Layout" view to see even more in-depth information and padding gaps in your types.
Other Methods
MSVC, at compile time
With MSVC, you can use this more simple approach, though it doesn't work with Clang or G++:
Then inside code:
The result here is also very direct:
At runtime, MSVC, Clang or G++
If you can wait until runtime, you can use this function:
MSVC:
Clang:
G++: