Skip to content

Cpp Coding Guidelines

Bernhard Manfred Gruber edited this page Oct 13, 2025 · 17 revisions

General

  1. Always use entities from cuda::std:: over std::. They work in host and device code, work with NVRTC, and help testing our implementation.
  2. Use CCCL internal macros over compiler/vendor-specific keywords in implementation headers. E.g., use _CCCL_HOST_DEVICE instead of __host__ __device_, or _CCCL_FORCEINLINE over __forceinline. Examples and documentation must not use these macros and should support vendor attributes and keywords instead. Tests should only use macros if they are strictly required for the test to work. For instance, _CCCL_HOST_DEVICE may be required for tests targeting non-CUDA backends.
  3. Fully qualify any reference to a libcu++ entity in any C++ library header with ::cuda::std::, ::cuda::, etc. This avoids ambiguities when users define namespaces called cuda themselves. Use just cuda::std in examples, tests and documentation.
  4. Doxygen comments should start with //!
  5. In documentation comments, we prefer the use of @c when referring to code entities and @brief and so on for doxygen commands
  6. Macros for function attributes, like _CCCL_HOST_DEVICE, should be ordered before declaration specifiers like constexpr or static
  7. Don't include libcu++ detail headers (starting with __) in downstream projects (like CUB, Thrust, etc.). Always prefer the public headers. (we are revising this to reduce compile time)
  8. Comments should express what the code cannot say. They complement code. Before writing an explanatory comment, consider whether refactoring the code could allow the code to express the same. This avoids code and comments getting out of sync.

libcu++

  1. Always fully qualify function calls, even to functions in the same namespace. This avoids ADL.
  2. Defaulted constructors should be marked with _CCCL_HIDE_FROM_ABI
  3. libcu++ headers like <cuda/foo> are strict supersets of <cuda/std/foo> and thus always include the corresponding <cuda/std/...> header.

CUB and Thrust

  1. All user-defined names for entities should use snake_case, except for template parameters, which use PascalCase, and macros, which use ALL_CAPS.

Licensing

CCCL uses a mix of different licenses for historical reasons.

  1. Any net new file should be licsensed under Apache-2.0 WITH LLVM-exception.
  2. For files with license headers, strongly prefer a 2-line SPDX header like:
// SPDX-FileCopyrightText: Copyright (c) 2025, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Clone this wiki locally