Skip to content

Guidelines Support Library (GSL)

Developer UtilitiesUtilitiesC++

What it is

The Guidelines Support Library (GSL) is a set of C++ utilities developed to help programmers follow the C++ Core Guidelines. It provides types and functions such as span, not_null, owner, and utilities for safer memory and pointer usage.

GSL provides utility types such as span for safe array handling, not_null for non-null pointers, and owner annotations for ownership semantics. It integrates seamlessly with modern C++ projects.

Installation

vcpkg install ms-gsl

Getting started

The smallest useful thing you can do with it, and what each part means.

Using span
#include <gsl/span>
#include <iostream>
#include <vector>

int main() {
    std::vector<int> v = {1, 2, 3, 4, 5};
    gsl::span<int> s(v);
    for (auto x : s) std::cout << x << " ";
    return 0;
}
A `span` provides a safe view over a contiguous sequence of elements without owning them.
Using not_null
#include <gsl/gsl>
#include <iostream>

void process(gsl::not_null<int*> ptr) {
    std::cout << *ptr << std::endl;
}

int main() {
    int x = 42;
    process(&x); // OK
    // process(nullptr); // compile-time error
}
`not_null` enforces at compile time that a pointer cannot be null.

Advanced usage

Where the library earns its place over a simpler alternative.

Owner annotations
#include <gsl/gsl>
#include <iostream>

void free_resource(gsl::owner<int*> ptr) {
    delete ptr;
}

int main() {
    gsl::owner<int*> data = new int(10);
    free_resource(data);
}
`owner<T*>` documents ownership semantics and helps static analyzers detect leaks.
Narrow casting
#include <gsl/gsl>
#include <iostream>

int main() {
    int x = 300;
    char c = gsl::narrow<char>(x); // runtime check for narrowing conversion
    std::cout << (int)c << std::endl;
}
`gsl::narrow` performs narrowing casts with runtime checks to prevent unsafe conversions.
Ensuring contracts
#include <gsl/gsl_assert>
#include <iostream>

int divide(int a, int b) {
    Expects(b != 0); // precondition
    return a / b;
}

int main() {
    std::cout << divide(10, 2) << std::endl;
}
Uses `Expects` and `Ensures` macros to declare preconditions and postconditions.

Errors and fixes

The failures you are most likely to hit, and what actually resolves them.

Invalid span access
Ensure the underlying container is not destroyed while span is in use.
Null pointer passed to not_null
Refactor to avoid null usage or wrap with `std::optional` where applicable.
Narrowing cast failed
Use a wider type or validate inputs before applying `narrow`.

Best practices

  • Use `span` instead of raw pointers or array references for safe and expressive code.
  • Mark ownership explicitly using `owner<T*>` to improve readability and analysis.
  • Use `not_null` whenever null pointers are not valid inputs.
  • Adopt `narrow` for safe casting between numeric types.
  • Leverage `Expects` and `Ensures` macros to enforce contracts in critical functions.

Background

Why it exists, and what it was reacting to.

The GSL was originally developed by Microsoft as part of the C++ Core Guidelines project led by Bjarne Stroustrup and Herb Sutter. Its purpose is to provide concrete implementations of safety-oriented types that enforce best practices and help developers write more robust and secure C++ code.