Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions docs/coding-guidelines/clr-code-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -1260,7 +1260,9 @@ See the big block comment at the start of [src\inc\contract.h][contract.h].

The C and C++ standard headers are available for usage in the CoreCLR code-base. However, there are restrictions on using the standard-provided APIs for code that will run as part of CoreCLR.

Code that will only run in other processes, such as `createdump` or other extraneous tools, do not have the same set of restrictions.
Code that will only run in other processes, such as `createdump` or other extraneous tools, have less restrictions.

For Linux builds, we build against an older C++ runtime to support older Linux distributions, but we bundle a newer C++ Standard Library implementation. This means CoreCLR code can use new C++ library features, but there may be some corners where particular features are not supported and fail at link time. Those features are not supported in CoreCLR code and should be avoided.

### <a name="2.11.1"></a> 2.11.1 Do not use wchar_t

Expand All @@ -1276,13 +1278,11 @@ For example, `std::vector<T>::at()` should not be used as it may throw an `std::

The POSIX API `setenv` is not thread safe with `getenv` and can lead to crashes. CoreCLR provides a `PAL_getenv` API that is thread-safe. This API should be used instead when on non-Windows platforms.

### <a name="2.11.4"></a> 2.11.4 Limit usage of standard template types in shipping executables

For Linux x64 and amd64 platforms, we build against a very old libstdc++, the version that shipped with Ubuntu 16.04. As a result, we strive to reduce our usage of template types (where code from the headers will be inserted into our binaries) in shipping executables and libraries.
### <a name="2.11.4"></a> 2.11.4 Do not use C++ Standard Library types

This rule applies to both `coreclr` as well as shipping external executables like `createdump`.
Using types and algorithms from the C++ standard is supported within the CoreCLR code base; however, we do not support it in our DAC/cDAC tooling. Do not use C++ Standard-defined containers, smart pointers, etc. for any fields accessed by the DAC or cDAC. Only use our collections that have cDAC contracts when you need to expose them for diagnostic tooling.

For non-shipping native code, like the `superpmi` tools suite, standard headers can be used without limitation.
For cases where diagnostic tooling integration is not required, you may use C++ Standard-defined types and algorithms meeting the C++ standard version CoreCLR builds with (defined in [eng/native/configurecompiler.cmake](../../eng/native/configurecompiler.cmake)).

@AaronRobinsonMSFT AaronRobinsonMSFT Aug 15, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would add a note that standard library must run in place where the following are satisfied:

  • It is not permitted to run under NOTHROW, unless the API is marked with noexcept.
  • It is never permitted to run under MODE_COOPERATIVE.

It is preferred to keep standard library code and related callbacks/lambdas used in algorithms etc., under the STANDARD_VM_CONTRACT contract.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm curious about the reason here. It's straight to understand the noexcept requirement, but not straight about cooperative mode restriction.

And also, are there any STL component considered "trivial enough" for safe usage anywhere? For example, I can't imagine where <bits> can't be used.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

but not straight about cooperative mode restriction.

It is far too easy to reach for a standard library collection or algorithm and create a GC starvation issue. We're being selective about this because there is an inherent cost to consuming standard library APIs and not truly understanding how they will behave.

And also, are there any STL component considered "trivial enough" for safe usage anywhere?

No. Using more standard library collections and algorithms is, at least for now, going to be limited to actual cases where there is measurable benefits. We will not accept wholesale replacements of our built-in collections for say std::vector<> or arbitrary replacement of holders for std::unique_ptr<>. The group of maintainers needs to get comfortable with best practices and when and where we can modernize the C++ without creating a maintenance burden for servicing or unlocking undefined behavior that compilers can then optimize in unexpected ways.


## <a name="2.12"></a>2.12 Is your code DAC compliant?

Expand Down
9 changes: 9 additions & 0 deletions eng/pipelines/common/platform-matrix.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ jobs:
buildConfig: ${{ parameters.buildConfig }}
helixQueueGroup: ${{ parameters.helixQueueGroup }}
crossBuild: true
cxxStandardLibrary: libc++
cxxStandardLibraryStatic: true
cxxAbiLibrary: libstdc++
Comment on lines +46 to +48
${{ insert }}: ${{ parameters.jobParameters }}

# Linux arm64
Expand All @@ -69,6 +72,9 @@ jobs:
buildConfig: ${{ parameters.buildConfig }}
helixQueueGroup: ${{ parameters.helixQueueGroup }}
crossBuild: true
cxxStandardLibrary: libc++
cxxStandardLibraryStatic: true
cxxAbiLibrary: libstdc++
${{ insert }}: ${{ parameters.jobParameters }}

# Linux musl x64
Expand Down Expand Up @@ -230,6 +236,9 @@ jobs:
buildConfig: ${{ parameters.buildConfig }}
helixQueueGroup: ${{ parameters.helixQueueGroup }}
crossBuild: true
cxxStandardLibrary: libc++
cxxStandardLibraryStatic: true
cxxAbiLibrary: libstdc++
${{ insert }}: ${{ parameters.jobParameters }}

- ${{ if containsValue(parameters.platforms, 'linux_x64_sanitizer') }}:
Expand Down
Loading