Skip to content
Open
Show file tree
Hide file tree
Changes from 3 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
1 change: 1 addition & 0 deletions docs/project/principles/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,6 @@ wants to pursue, as well as those we want to exclude.
- [Information accumulation](information_accumulation.md)
- [Low context-sensitivity](low_context_sensitivity.md)
- [Prefer providing only one way to do a given thing](one_way.md)
- [Safety](safety.md)
- [One static open extension mechanism](static_open_extension.md)
- [Success criteria](success_criteria.md)
81 changes: 81 additions & 0 deletions docs/project/principles/safety.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
# Safety

<!--
Part of the Carbon Language project, under the Apache License v2.0 with LLVM
Exceptions. See /LICENSE for license information.
SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-->

<!-- toc -->

## Static Checking

For any sufficiently expressive programming language, it is
undecidable whether the execution of programs in that language
will have interesting properties.

*Static checking* is a compile-time method to ensure program properties through
analysis and annotations that describe intended behavior.

Carbon aims to provides rigorous memory safety guarantees
through static checking. This requires navigating a field of tension
between safety and expressivity. Carbon's statically checked safety
guarantees should not come at the price of losing possibility to cover
realistic programming use cases.

Static checking cannot fully eliminate the need for dynamic techniques
for safety (e.g. bounds checks) but it can provide constraints on
runtime program behaviors to minimize such checks.

## Strict and Permissive Carbon

The goals of Carbon include incremental migration from C++, which does not
come withs statically checked safety guarantees. Further,
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
come withs statically checked safety guarantees. Further,
come with as many statically checked safety guarantees. Further,

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think this is a recurring source of misunderstanding where I may need to adapt my writing. I see "safety" as a global property (like "type soundness"), a language either has it or not, whereas your suggestion indicates that there may be multiple different safety guarantees.
I believe words like "rigorous memory safety" and "memory-safe language" suggests an overall guarantee that all memory-safety bugs are prevented. C++ does not come with any guarantee here, actually, does it help if I change to singular?

interactions with system components not written in Carbon place a limit
on safety guarantees.

For this reason, Carbon's design distinguishes between a *strict* and a *permissive* variant of the
Copy link
Contributor

Choose a reason for hiding this comment

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

Should set up pre-commit according to https://github.com/carbon-language/carbon-lang/blob/trunk/docs/project/contribution_tools.md to get auto-formatting.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

language and clarifies the interaction and boundary between these variants.

A strict-Carbon program fragment is only accepted by the compiler
if execution is guaranteed to be entirely free of safety-related execution errors
and its behavior with respect to safety is predictable.
Copy link
Contributor

Choose a reason for hiding this comment

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

Except to the extent that it performs (explicitly marked) unsafe operations, including things like calls to C++ code.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The next section "partial safety" goes into this.
I have added a sentence saying that a safety argument must be provided in some form when an unsafe op is performed.


A permissive-Carbon program is accepted independent without any guarantee
whether its execution may lead to safety errors. In particular, a
permissive-Carbon program fragment can call C++ code. The
programmer does not have to give additional information to the compiler
which is necessary for checking safety.
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think this is an accurate characterization of our plans. I think that there are limits to the checking that will be possible, dependent on the extent of safety annotations in the code and use of unsafe operations, but there is an expectation that permissive-Carbon will not disregard safety considerations entirely. My expectation is that it will be safer than C++, particularly by default, and some dangerous constructs will only be available with explicit unsafe markings.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Reworded, but I believe there is a difference between permissive and strict Carbon? I though it was very specific that permissive Carbon can be without any markings.
I did clarify that permissive Carbon may support adding markings and thus getting to "partial" safety, avoid some bugs.


## Partial Safety and Gradual Ramp-up

While absence of safety-related errors is a property of a program as
a whole, the design must specify the boundary and interaction between
strict-Carbon and permissive-Carbon fragments in a way that benefits
from partial safety guarantees.

A strict-Carbon program fragment may safely interact with a permissive-Carbon fragment
if the conditions for safe execution are met.

It will be possible and necessary to *assume* such safety conditions. In permissive
Copy link
Contributor

Choose a reason for hiding this comment

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

The word assume here is too strong. The expectation is that optimizations will not be performed based only on those assumptions, and it generally won't be undefined behavior if those safety conditions are dynamically violated.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Can you clarify what you mean? Imagine we have strict Carbon program that calls permissive Carbon function foo(p) with a pointer argument and foo will have some effects on memory, but lack effect and type annotations and such.

So we mark it as "unsafe" and we simply state the effect, so that the program fragment makes sense in strict Carbon. This statement is an "assumption of safety conditions" that I mean here, it cannot be provided or proven by the compiler.

I do not follow what you are saying. If we could guarantee absence of undefined behavior in permissive Carbon, then this is already a perfectly memory-safe language and we wouldn't have a need for strict Carbon anymore. Even reading memory by dereferencing a single pointer is an unsafe operation that can provoke undefined behavior (we don't know what the read returns and what the program will do afterwards), and we won't be willing to pay the overhead for runtime-instrumentation of every read.

code, the responsibility for safety lies with the programmer.
Carbon's safety model may support communicating part or all of the assumed
information to the compiler which can make use of it for safety checking.

It must further be possible to turn permissive-Carbon code into safe-Carbon by gradual adoption
Copy link
Contributor

Choose a reason for hiding this comment

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

There is a switch here from strict-Carbon to safe-Carbon that I think is an inconsistency, but it could just be a gap in the explanation:
We could say safe-Carbon is a subset of both strict-Carbon and permissive-Carbon, the subset that only uses safe constructs. The difference between strict-Carbon and permissive-Carbon has more to do with whether unsafe constructs are marked, and whether safety annotations are required.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I just mixed up strict and safe, but my understanding is that strict Carbon is supposed to be that rigorously memory safe language variant.

of safety-related annotations.

## Simplicity and Ease of Understanding

Annotations for static checking need to be [easy to read and write](../goals.md#code-that-is-easy-to-read-understand-and-write), and program safety must
be attainable without being forced to fully rewrite migrated C++ and
without performance cost.

The rules that determine whether a strict-Carbon program is accepted
should be documented and easy to understand.

Different build modes never change the rules that make
safe-Carbon safe (safe-Carbon is safe in any build mode).
They may affect behavior and performance characteristics of
Carbon programs as a whole.

Loading