Skip to content

Commit 4b6e613

Browse files
Links
1 parent 9e04550 commit 4b6e613

File tree

3 files changed

+21
-19
lines changed

3 files changed

+21
-19
lines changed

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "ndd"
3-
version = "0.2.9"
3+
version = "0.2.10"
44
edition = "2024"
55

66
license = "BSD-2-Clause OR Apache-2.0 OR MIT"

README.md

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,28 @@
1-
![GitHub Actions
2-
results](https://github.com/peter-lyons-kehl/ndd/actions/workflows/main.yml/badge.svg)
1+
[![GitHub Actions
2+
results](https://github.com/peter-lyons-kehl/ndd/actions/workflows/main.yml/badge.svg)](https://github.com/peter-lyons-kehl/ndd/actions)
33

44
# Summary
5+
## Purpose
56

6-
`ndd` (Non-De-Duplicated) is a zero-cost transparent wrapper. For `static` variables that do **not**
7+
`ndd` (Non-De-Duplicated) is a zero-cost transparent wrapper for `static` variables that do **not**
78
share memory with any other `static` or `const` (or local) variables (or literals). Use for `static`
89
data (single variables/arrays/slices) referenced with references/slices/pointers that are **compared
910
by address**.
1011

11-
# Use
12+
## Use
1213

1314
Use [`ndd::NonDeDuplicated`] to wrap your static data (other than string literals (`&str`) or C
1415
string literal bytes). Use it for (immutable) `static` variables only.
1516

1617
Use [`ndd::NonDeDuplicatedStr`] and [`ndd::NonDeDuplicatedCStr`] to wrap static string slices
1718
(`&str`) and C strings (owned bytes that defer to `&CStr`). These two types need a `const` generic
18-
parameter `N`, which is the length (in bytes). There is no way around this (in stable Rust). On
19+
parameter `N`, which is the length (in bytes). There is no way around this (on stable Rust). On
1920
`nightly` Rust you can use `ndd::infer:NonDeDuplicatedStr` and `ndd::infer:NonDeDuplicatedCStr` from
2021
**odd-numbered** (`-nightly`) version of `ndd` instead.
2122

2223
See unit tests in [`src/lib.rs`], and [`cross_crate_demo_fix/callee/src/lib.rs`].
2324

24-
# Problem
25+
## Problem
2526

2627
Rust (or, rather, LLVM) by default de-duplicates or reuses **addresses** of `static` variables in
2728
`release` builds. And somewhat in `dev` (debug) builds, too. For most purposes that is good: The
@@ -44,22 +45,22 @@ That does work out of the box when the client passes a reference/slice defined a
4445
`static` gets its own memory space (even with the default `release` optimizations). See a test
4546
[`src/lib.rs` -> `tests_without_ndd` -> `addresses_unique_between_statics()`].
4647

47-
However, there is a problem (caused by de-duplication in `release`, and for some types even in `dev
48-
or `miri). It affects ("ordinary") `const` values/expressions that equal in value to any `static`
49-
(whether it's a `static` variable, or a static literal), which may be your designated `static`.
50-
Rust/LLVM re-uses address of one such matching `static` for references to any equal value(s) defined
51-
as `const`. See <!-- padding for re-wrap -->
52-
[`src/lib.rs` -> `tests_without_ndd` -> `u8_global_const_and_global_static_release()`]. Such
53-
`const`, `static` or literal could be in 3rd party code, even private. (See
54-
[`cross_crate_demo_bug/`].)
48+
However, there is a problem (caused by de-duplication in `release` builds, and for some types even
49+
in `dev` or [`MIRI`]). It affects ("ordinary") `const` values/expressions that equal in value to any
50+
`static` (whether it's a `static` variable, or a static literal), which may be your designated
51+
`static`. Rust/LLVM re-uses address of one such matching `static` for references to any equal
52+
value(s) defined as `const`. See <!-- padding for re-wrap --> [`src/lib.rs` -> `tests_without_ndd`
53+
-> `u8_global_const_and_global_static_release()`]. Such `const`, `static` or literal could be in 3rd
54+
party code, even private. (See [`cross_crate_demo_bug/`].)
5555

5656
Things get worse: `dev` builds don't have this consistent:
5757

5858
- For some types (`u8`, numeric primitive-based enums) `dev` builds don't reuse `static` addresses
5959
for references/slices to `const` values. But
6060
- For other types (`str`), `dev` builds do reuse them...
6161

62-
`MIRI` reuses `static` addresses even less (than `dev` does), but it still does reuse them sometimes
62+
[`MIRI`] reuses `static` addresses even less (than `dev` does), but it still does reuse them
63+
sometimes
6364
- for example, between byte (`&CStr`) literals (`b"Hello"`) and equal string (`&str`) literals
6465
(technically, subslices: `"Hello"`).
6566

@@ -80,7 +81,7 @@ lto = "fat"
8081
opt-level = 2
8182
```
8283

83-
# Solution
84+
## Solution
8485

8586
[`ndd::NonDeDuplicated`] uses [`core::cell::Cell`] to hold the data passed in by the user. There is
8687
no mutation and no mutation access. The only access it gives to the inner data is through shared
@@ -246,7 +247,7 @@ run on Alpine Linux (without `libc`) and are POSIX-compliant:
246247
- `cargo doc --no-deps --quiet`
247248
- `cargo test`
248249
- `cargo test --release`
249-
- with [MIRI](https://github.com/rust-lang/miri):
250+
- with [`MIRI`]
250251
- `rustup install nightly --profile minimal`
251252
- `rustup +nightly component add miri`
252253
- `cargo +nightly miri test`
@@ -310,6 +311,7 @@ The following side fruit is `std`-only, but related: `std::sync::mutex::data_ptr
310311
[`core::ptr::eq`]: https://doc.rust-lang.org/1.86.0/core/ptr/fn.eq.html
311312
[`core::ptr::addr_eq`]: https://doc.rust-lang.org/1.86.0/core/ptr/fn.addr_eq.html
312313
[`src/lib.rs` -> `tests_without_ndd` -> `addresses_unique_between_statics()`]: src/lib.rs#L269
314+
[`MIRI`]: https://github.com/rust-lang/miri
313315
[`src/lib.rs` -> `tests_without_ndd` -> `u8_global_const_and_global_static_release()`]:
314316
src/lib.rs#L278
315317
[`cross_crate_demo_bug/`]: cross_crate_demo_bug/

0 commit comments

Comments
 (0)