c++ - 幻影类型是否与原始类型具有相同的对齐方式?

标签 c++ struct types language-lawyer memory-alignment

考虑以下包含一些环境值的结构:

struct environment_values {
  uint16_t humidity;
  uint16_t temperature;
  uint16_t charging;
};

我想为这些具有幻像类型*的值添加一些附加信息,并同时使它们的类型不同:

template <typename T, typename P>
struct Tagged {
    T value;
};

// Actual implementation will contain some more features
struct Celsius{};
struct Power{};
struct Percent{};

struct Environment {
  Tagged<uint16_t,Percent> humidity;
  Tagged<uint16_t,Celsius> temperature;
  Tagged<uint16_t,Power>   charging;
};

Environment的内存布局和environment_values一样吗?这是否也适用于混合类型布局,例如:

struct foo {
    uint16_t value1;
    uint8_t  value2;
    uint64_t value3;
}

struct Foo {
    Tagged<uint16_t, Foo>  Value1;
    Tagged<uint8_t , Bar>  Value2;
    Tagged<uint64_t, Quux> Value3;
}

到目前为止,我尝试过的所有类型都有以下断言:

template <typename T, typename P = int>
constexpr void check() {
    static_assert(alignof(T) == alignof(Tagged<T,P>), "alignment differs");
    static_assert(sizeof(T)  == sizeof(Tagged<T,P>),  "size differs");
}

// check<uint16_t>(), check<uint32_t>(), check<char>() …

由于标记和未标记变体的大小也相同,我答案应该是肯定的,但我想有一些确定性。

* 我不知道在 C++ 中如何调用这些标记值。 “强类型类型定义”?我取自 Haskell 的名字。

最佳答案

标准在 [basic.align]/1 中提及:

Object types have alignment requirements (3.9.1, 3.9.2) which place restrictions on the addresses at which an object of that type may be allocated. An alignment is an implementation-defined integer value representing the number of bytes between successive addresses at which a given object can be allocated. An object type imposes an alignment requirement on every object of that type; stricter alignment can be requested using the alignment specifier (7.6.2).

此外,[basic.compound]/3 ,提及:

The value representation of pointer types is implementation-defined. Pointers to layout-compatible types shall have the same value representation and alignment requirements (6.11). [Note: Pointers to over-aligned types (6.11) have no special representation, but their range of valid values is restricted by the extended alignment requirement].

因此,可以保证布局兼容的类型具有相同的对齐方式。

struct { T m; }T 布局不兼容。

正如所指出的 here ,为了使两个元素布局兼容,那么它们都必须是标准布局类型,并且它们的非静态数据成员必须以相同的类型和相同的顺序出现。

struct { T m; } 只包含一个 T,但 T 是一个 T 所以它不能包含一个 T 作为它的第一个非静态数据成员。

关于c++ - 幻影类型是否与原始类型具有相同的对齐方式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46425250/

相关文章:

c++ - Affdex-SDK 帧检测器的像素顺序?

c++ - 使用 C++ 的 Unix 命令

c++ - 为什么复制对比复制结构慢?

c# - .NET 整数与 Int16?

python - 我怎么知道在 Python 中使用什么数据类型?

C++11 传递 POD 类型的值比 const 引用差

c - 修复了带有空格键和 EOF 检查的字符串

python-3.x - 如何从 Python Dict 创建 Protobuf Struct?

c - 在C函数中返回struct

types - 如果有的话,您需要向依赖类型系统添加什么才能获得模块系统?