xiedeacc
发布于 2025-06-27 / 31 阅读
0
0

C++/C/Rust内存布局

to be finished

三特征对比表

特征

std::is_trivially_copyable_v

std::is_standard_layout_v

std::is_pod_v (已弃用)

本质要求

可安全memcpy

内存布局可预测

兼容C的"纯数据"类型

满足条件

平凡析构+平凡复制操作

统一访问权限+无虚元素

同时满足左列两项

布局保证

❌ 无布局保证

✅ 严格顺序布局

✅ 继承标准布局保证

C兼容性

❌ 不保证兼容

✅ 完全兼容C结构体

✅ 完全兼容

用户定义构造函数

❌ 禁止

✅ 允许

❌ 禁止

虚函数/虚继承

✅ 允许(需平凡)

❌ 绝对禁止

❌ 禁止

不同访问权限成员

✅ 允许

❌ 禁止

❌ 禁止

引用类型成员

✅ 允许

❌ 禁止

❌ 禁止

典型用途

安全内存复制

内存映射/C交互

历史遗留的兼容要求

  • 所有POD类型都是平凡可复制且是标准布局的。

  • 但反过来不成立:一个类型可以是平凡可复制但不是标准布局(例如,具有不同访问权限的非静态成员),或者是标准布局但不是平凡可复制(例如,有用户定义的构造函数,但满足标准布局)。

标准布局(standard layout)的要求比是平凡可复制(trivially copyable)更加严格吗?

实际上,这两个概念是独立的,并没有直接包含关系。但是,标准布局类型通常也是平凡可复制的(除非有非平凡的构造函数等)。然而,也存在一些类型是平凡可复制的但不是标准布局(例如,有不同访问权限的成员变量),以及一些是标准布局但不是平凡可复制的(例如,有自定义构造函数的类型)。

he is_trivial Family

These traits all deal with triviality, default construction, destruction, copying, and moving — i.e. “does this type have simple, compiler-generated semantics?”

Trait

Meaning

Notes

std::is_trivial<T>

The type has trivial special member functions (default ctor, copy/move ctor, copy/move assignment, destructor).

A zero-initialized object is valid. All members are trivial.

std::is_trivially_copyable<T>

The type can be copied bitwise (memcpy safe).

Superset of is_trivial.

std::is_trivially_constructible<T, Args...>

The type can be constructed trivially from Args... (no user-provided code runs).

Checks for trivial construction form.

std::is_trivially_default_constructible<T>

is_trivially_constructible<T> with no arguments.

C++11+.

std::is_trivially_copy_constructible<T>

The copy constructor is trivial.

Used for optimization in containers.

std::is_trivially_move_constructible<T>

The move constructor is trivial.

std::is_trivially_assignable<T, U>

Assignment from U to T is trivial.

C++11+.

std::is_trivially_copy_assignable<T>

Copy assignment operator is trivial.

std::is_trivially_move_assignable<T>

Move assignment operator is trivial.

std::is_trivially_destructible<T>

Destructor is trivial (does nothing).

Often means no user-managed resource cleanup.

he is_standard_layout Family

These traits relate to the memory layout and structural properties of a type:
how its fields are organized, whether it has a stable ABI, and whether it can safely interop with a C struct or be used in packed storage.

Trait

Meaning

Notes

std::is_standard_layout<T>

Type has a C-compatible layout: predictable field order, ABI-safe.

Layout-only trait — doesn’t imply triviality.

std::is_aggregate<T>

Type can be aggregate-initialized (no private/protected constructors, virtuals, etc.).

Often overlaps with standard-layout types but not required.

std::is_empty<T>

Type has no non-static data members (only vtable / alignment fillers maybe).

Related to empty base optimization.

std::is_final<T>

The class can’t be derived from.

Affects inheritance / layout.

std::is_polymorphic<T>

Type has virtual functions.

Not standard-layout if also has data members.

std::is_abstract<T>

Type has at least one pure virtual function.

Never standard-layout.

std::is_class<T>, std::is_union<T>, std::is_enum<T>

Form category for structural analysis.

Often used with layout traits.


🧮 Summary Table of Both Families

Category

Trait

Core Purpose

Affects Layout

Affects Trivial Semantics

Safe for memcpy

Trivial

is_trivial

All special member functions trivial

Trivial

is_trivially_copyable

Bitwise copy safe

⚙️ maybe

Trivial

is_trivially_constructible (various forms)

Construction doesn’t run code

Trivial

is_trivially_destructible

Destructor is do-nothing

Layout

is_standard_layout

C-like layout rules

🚫

🚫

Layout

is_aggregate

Aggregate-init allowed

🚫

🚫

Layout

is_empty

No non-static data

🚫

🚫

Layout

is_final, is_polymorphic

Inheritance/virtual traits

✅ (indirectly)

🚫

🚫


🧠 Conceptual Group Picture (Textual Venn Summary)

                     ┌──────────────────────────────┐
                     │   Trivially Copyable Types   │
                     │  (memcpy safe)               │
                     │   ┌──────────────────────┐   │
                     │   │   Trivial Types      │   │
                     │   │  (zero-init safe)    │   │
                     │   └──────────────────────┘   │
                     └──────────────────────────────┘

     ┌────────────────────┐
     │ Standard Layout    │
     │ (C layout rules)   │
     └────────────────────┘
        ↕ may overlap

TL;DR

  • 🧩 Trivial/Trivially Copyable family → defines when special member functions do nothing fancy and objects can be bit‑copied or zero‑initialized safely.

  • 🧱 Standard Layout family → defines when objects have predictable, C‑compatible memory layout.

  • is_trivialis_trivially_copyable, but not vice versa.

  • 🚫 is_standard_layout is independent — describes memory structure, not behavior.


Would you like me to render this as a visual Venn diagram (HTML/SVG), showing how is_trivial, is_trivially_copyable, and is_standard_layout overlap?


评论