幻像类型与原始类型具有相同的对齐方式吗? [英] Does a phantom type have the same alignment as the original one?

查看:88
本文介绍了幻像类型与原始类型具有相同的对齐方式吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Consider the following struct that contains some environment values:

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

我想向那些具有幻像类型*的值添加一些其他信息,并同时使其类型不同:

I would like to add some additional information to those values with a phantom type* and make their types distinct at the same time:

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相同吗?这是否也适用于混合类型的布局,例如:

Is the memory-layout of Environment the same as environment_values? Does this also hold for mixed type layouts, e.g.:

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;
}

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

For all types I've tried so far, the following assertions held:

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>() …

由于标记和未标记变体的大小也相同,所以我猜是,但是我希望可以肯定.

Since the size of the tagged and untagged variants is also the same, I guess the answer should be yes, but I would like to have some certainty.

*我不知道如何在C ++中调用这些标记的值. 强类型typedef"?我是从Haskell取这个名字的.

推荐答案

该标准在 [basic.align]/1 :

对象类型具有对齐要求(3.9.1、3.9.2),这些要求放在 对该类型的对象可能位于的地址的限制 已分配. 对齐方式是实现定义的整数值 代表连续地址之间的字节数 可以分配给定的对象.对象类型强制对齐 对该类型的每个物体的要求;可以更严格地对齐 使用对齐说明符(7.6.2)请求.

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 提到:

指针类型的值表示形式是实现定义的. 指向 layout-compatible类型的指针应具有相同的值 表示和对齐要求(6.11). [注意:指向 过度对齐的类型(6.11)没有特殊的表示形式,但是它们的 有效值范围受扩展对齐方式的限制 要求].

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].

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

As a result, there is a guarantee that layout-compatible types have the same alignment.

struct { T m; }T与布局不兼容.

如指出的那样

As pointed here, in order for two elements to be layout compatible then they both have to be standard-layout types, and their non-static data members must occur with the same types and in the same order.

struct { T m; }仅包含T,但是TT,因此它不能包含T作为其第一个非静态数据成员.

struct { T m; } contains just a T, but T is a T so it cannot contain a T as its first non-static data member.

这篇关于幻像类型与原始类型具有相同的对齐方式吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆