Microsoft GSL: the Core Guidelines support types, header-only and C++14
Guidelines Support Library
At a glance
- What is it?
- Microsoft's implementation of the C++ Core Guidelines Support Library ships as inline headers for C++14 and later. It is most useful when you want not_null, span and narrow in a codebase that cannot move to newer standard library equivalents.
- Who is it for?
- Adopt Microsoft GSL if you are writing C++14 or later and want not_null, gsl::span and narrow in interfaces without waiting for newer standard library equivalents. Skip it if you already compile against std::span and std::string_view, since gsl::span keeps bounds checking that std::span does not.
- Can I use it commercially?
- Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
- Is it still maintained?
- Yes. The repository last received commits 1 day ago.
- What is it written in?
- Mainly C++, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 30, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What Microsoft GSL actually gives a C++ codebase
The C++ Core Guidelines describe a set of types and functions that make interfaces express intent. Microsoft GSL is one implementation of that list. The README states that "the entire implementation is provided inline in the headers under the gsl directory", and that the implementation generally assumes a platform with C++14 support. There is no compiled library to link, no runtime to initialise, and no build step required to consume it.
The target reader is an engineer maintaining C++ that cannot yet rely on the newest standard library. gsl::not_null restricts a pointer or smart pointer to hold non-null values. gsl::span is described as a view over a contiguous sequence of memory, based on the standardized std::span, with the difference that gsl::span enforces bounds checking. gsl::narrow is a checked cast that can throw gsl::narrowing_error, while gsl::narrow_cast is a synonym for static_cast. Expects and Ensures are precondition and postcondition assertions that terminate on failure.
This is a small surface area on purpose. If you want a framework, this is not one. If you want three or four types that catch a class of mistakes at the boundary of a function, this is exactly the scope.
How the header layout and the assertion model work
The repository keeps the implementation in include/gsl, with some types broken out into their own headers such as gsl/span. The README notes that it is simplest to include gsl/gsl and gain access to the entire library, which is the usual way to consume it. Because everything is inline, the cost of including the umbrella header is compile time, not link time.
Expects and Ensures are the interesting design point. They are assertions, and on failure they terminate. They are not exceptions you can catch and recover from, and they are not a logging mechanism. That is a deliberate choice: a violated precondition is a bug, and the library stops the process rather than letting execution continue in an invalid state. If your product needs to degrade gracefully on a bad input, you should validate at the boundary and use Expects only for conditions that indicate programmer error.
GSL_SUPPRESS is a macro that takes an argument and turns it into [[gsl::suppress(x)]] or [[gsl::suppress("x")]] depending on the compiler. That is aimed at static analysis tooling rather than runtime behaviour, and it is the part of the library most tied to a specific toolchain story.
Installing Microsoft GSL and a first use
The README points at vcpkg through its badge for the ms-gsl package, and the repository carries a CMakeLists.txt and a CMakePresets.json at the top level. The documented package name is ms-gsl:
vcpkg install ms-gslAfter that, the headers are available through the vcpkg toolchain file when you configure your own project. If you prefer to vendor the source, clone the repository and point your include path at include/, because the headers live under include/gsl.
A first real use is a function that takes a non-null pointer and a bounded view. The README gives this example for the umbrella header:
#include <gsl/gsl>Including that single header gives access to the entire library, which the README describes as the simplest way to consume it. From there, the types you reach for first are gsl::not_null on a pointer parameter and gsl::span on a contiguous range, with Expects used only for conditions that cannot happen in correct code, since Expects terminates the process on failure.
Where Microsoft GSL is the wrong tool
The supported features table lists several Core Guidelines items as unsupported. span_p, stack_array, move_owner and [[implicit]] are all marked as not supported. The entire Concepts row is marked unsupported. If your design depends on span_p or on a stack-allocated array owner, this library does not provide it, and you should not plan around it.
The second limitation is the C++14 baseline combined with the bounds checking choice. gsl::span enforces bounds checking, which is a safety gain over raw pointer arithmetic but also means gsl::span is not a drop-in replacement for std::span in code that relies on std::span's unchecked operator[]. If you are on C++20 and already have std::span, adopting gsl::span adds a second view type to the codebase for a guarantee std::span does not make. That trade is defensible for safety-critical code and irritating for code that just wants a view.
Finally, Expects and Ensures terminate. Anywhere you want a recoverable error path, they are the wrong mechanism, and using them there will turn a handled error into a crash.
Microsoft GSL compared with the GNU Scientific Library
Search traffic around this name mixes two unrelated projects, and the confusion is worth naming. The GNU Scientific Library is also abbreviated GSL, and it is a numerical library: special functions, linear algebra, statistics, random number distributions. Microsoft GSL is a set of small vocabulary types for interface correctness. They share an acronym and nothing else.
The practical difference is what you link. GNU Scientific Library is a compiled C library that you build or install and then link against. Microsoft GSL is header-only C++ with no link step, and its contents are types like not_null and span rather than numerical routines. If you arrived here looking for a Bessel function, this repository will not help you. If you arrived here looking for a checked narrow cast, the other one will not.
Maintenance, licence and upgrade cost
The repository is not archived, and the last push was on 2026-09-18. The most recent release listed is v5.0.0 from 2026-08-26, preceded by v4.2.2 in 2026-05-20 and v4.2.1 in 2025-12-08. That is a slow but real release cadence, and the version numbers indicate that major bumps do happen, so pinning a tag rather than tracking main is the reasonable default.
Upgrade cost is low in the common case because the library is headers only. The things that can break are the assertion semantics and the span behaviour, both of which are behavioural rather than API-shaped. A jump from 4.x to 5.x is worth a read of the release notes before you take it, and the repository keeps docs/headers.md as the reference for each type.
The licence field is NOASSERTION, and the repository carries a LICENSE file plus a ThirdPartyNotices.txt that the README says covers Google Test, which is used for testing. Because the machine-readable licence field does not assert a specific identifier, read LICENSE yourself and have whoever handles licensing at your organisation confirm it before you ship. That is a factual gap in the metadata, not a legal opinion.
Editorial conclusion
Adopt Microsoft GSL if you are writing C++14 or later and want not_null, gsl::span and narrow in interfaces without waiting for newer standard library equivalents. Skip it if you already compile against std::span and std::string_view, since gsl::span keeps bounds checking that std::span does not. Before committing, check the licence file, because the repository is marked NOASSERTION, and confirm your toolchain matches the CMake minimum in CMakeLists.txt.
Frequently asked questions
How do I install Microsoft GSL?
The README points at vcpkg through the ms-gsl package badge, so vcpkg install ms-gsl is the documented route. You can also vendor the headers directly, since the implementation is inline under include/gsl.
What is Microsoft GSL?
It is Microsoft's implementation of the Guidelines Support Library, a set of functions and types suggested for use by the C++ Core Guidelines. The README describes it as header-only and generally assuming C++14 support.
Is Microsoft GSL the same as the GNU Scientific Library?
No. Both are abbreviated GSL, but Microsoft GSL provides interface types such as not_null, gsl::span and gsl::narrow, while the GNU Scientific Library is a numerical library. They share an acronym only.
Does Microsoft GSL require C++14 or newer?
The README states that the implementation generally assumes a platform that implements C++14 support. There is no compiled component, so the requirement is on your compiler and standard library, not on a linked binary.
Which Core Guidelines features does Microsoft GSL not implement?
The supported features table marks span_p, stack_array, move_owner and [[implicit]] as unsupported, and the Concepts row is unsupported as well. Everything else listed in the table, including owner, not_null, span, the zstring aliases, Expects, Ensures, final_action, finally, GSL_SUPPRESS, index, narrow and narrow_cast, is marked supported.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/microsoft-gsl)