标签: alignas

我在哪里可以在C++ 11中使用alignas()?

为了使我的代码标准化并使其更具可移植性,我更换了

#ifdef __GNUC__
typedef __attribute__((aligned(16))) float aligned_block[4];
#else
typedef __declspec(align(16)) float aligned_block[4];
#endif
Run Code Online (Sandbox Code Playgroud)

typedef float alignas(16) aligned_block[4];
Run Code Online (Sandbox Code Playgroud)

在C++ 11中.然而,gnu(4.8)并不喜欢这样但是抱怨

test.cc:3:9: warning: attribute ignored [-Wattributes]
  typedef float alignas(16) aligned_block[4];
                ^
test.cc:3:9: note: an attribute that appertains to a type-specifier is ignored
Run Code Online (Sandbox Code Playgroud)

而clang 3.2没有发出警告(即使有-Weverything -Wno-c++98-compat -pedantic).所以我想知道我上面的代码是否正确,更一般地说,我alignas()可以在哪里放置.

编辑(2013年4月):

该标准的相关文章是7.6.2,特别是7.6.2.1

对齐说明符可以应用于变量或类数据成员,但不应该应用于位字段,函数参数,catch子句的形式参数(15.3)或使用注册存储类说明符.对齐说明符也可以应用于类或枚举类型的声明.带省略号的对齐说明符是包扩展(14.5.3).

正如Red XIII已经挖出来的那样.但是,我不够专业,不知道这对我上面的测试意味着什么.

如果clang接受我的属性这一事实意味着什么,那么也许值得一提的是,当试图使用using指令代替a时typedef,clang也会抱怨.此外,与此问题的早期版本中的陈述相反,gcc不仅警告,而且实际上忽略了我对齐的愿望.

c++ alignment c++11 alignas

32
推荐指数
3
解决办法
1万
查看次数

如何使用alignas替换pragma pack?

我试图理解如何使用alignas,我想知道它是否可以替代pragma pack,我已经努力验证它但没有运气.使用gcc 4.8.1(http://ideone.com/04mxpI)我总是在STestAlignas下面获得8个字节,而使用pragma pack时它是5个字节.我想要的是使sizeof(STestAlignas)返回5.我尝试在clang 3.3上运行此代码(http://gcc.godbolt.org/)但我收到错误:

!!错误:对于'long'类型,请求的对齐小于8的最小对齐 - 正好在alignas使用之下.

那么也许对齐有最小的对齐值?

下面是我的测试代码:

#include <iostream>
#include <cstddef>
using namespace std;

#pragma pack(1)
struct STestPragmaPack {
  char c;
  long d;
} datasPP;
#pragma pack()

struct STestAttributPacked {
  char c;
  long d;
} __attribute__((packed)) datasAP;

struct STestAlignas {
  char c;
  alignas(char) long d;
} datasA;

int main() {
    cout << "pragma pack = " << sizeof(datasPP) << endl;
    cout << "attribute packed = " << sizeof(datasAP) << endl;
    cout << "alignas …
Run Code Online (Sandbox Code Playgroud)

c++ gcc c++11 alignas

12
推荐指数
1
解决办法
3007
查看次数

gcc过度对齐的新支持(alignas)

我在查找有关GCC的对齐新警告和gcc -faligned-new选项的更多信息时遇到了一些困难.在gcc 7.2.0上编译(没有--std = c ++ 17)并尝试定义一个对齐的结构,例如:

struct alignas(64) Foo { int x; }
Run Code Online (Sandbox Code Playgroud)

做一个简单的旧:

Foo * f = new Foo();
Run Code Online (Sandbox Code Playgroud)

给我以下警告和建议:

 alignas.cpp:36:25: warning: ‘new’ of type ‘Foo’ with extended alignment 64 [-Waligned-new=]
 Foo * f = new Foo();
                     ^
 alignas.cpp:36:25: note: uses ‘void* operator new(long unsigned int)’, which does not have an alignment parameter
 alignas.cpp:36:25: note: use ‘-faligned-new’ to enable C++17 over-aligned new support
Run Code Online (Sandbox Code Playgroud)

据我所知,默认情况下new只返回内存对齐alignof( std::max_align_t )(对我而言是16),但我不清楚的是,如果我传递-faligned-new,gcc现在会new代表我强制执行新的对齐吗?

不幸的是,关于这个的gcc文档非常缺乏.

c++ gcc gcc-warning alignas

9
推荐指数
1
解决办法
3682
查看次数

将operator new(sizeof(T)*N)返回的内存作为数组处理

在C中,可以使用malloc(sizeof(T)*N)分配动态数组,然后使用指针算法在此动态数组中获取i偏移的元素.

在C++中,可以使用operator new()以与malloc()相同的方式执行类似的操作,然后使用new(例如,可以在书中看到第13项的解决方案"Exceptional C++:47工程难题,编程问题和解决方案"通过Herb Sutter).如果您没有,则此问题的解决方案摘要如下:

T* storage = operator new(sizeof(T)*size);

// insert element    
T* p = storage + i;
new (p) T(element);

// get element
T* element = storage[i];
Run Code Online (Sandbox Code Playgroud)

对我来说,这看起来是合法的,因为我要求一大块内存,有足够的内存来容纳n个对齐的size = sizeof(T)元素.因为sizeof(T)应该返回一个对齐的元素的大小,并且它们在一块内存中一个接一个地放置,所以在这里使用指针算法是可以的.

然而,我随后指出了以下链接:http://eel.is/c++draft/expr.add#4http://eel.is/c++draft/intro.object#def:object并声称在C++运算符new()中没有返回一个数组对象,因此对它返回的内容进行指针算术并将其用作数组是未定义的行为,而不是ANSI C.

我不是很擅长这么低级别的东西而且我真的想通过阅读这个来理解:https ://www.ibm.com/developerworks/library/pa-dalign/或者这个:http:// jrruethe. github.io/blog/2015/08/23/placement-new/但我还是不明白,如果萨特是完全错误的?

我确实理解alignas在构造中是有意义的,例如:

alignas(double) char array[sizeof(double)];
Run Code Online (Sandbox Code Playgroud)

(c)http://georgeflanagin.com/alignas.php

如果数组看起来不在double的边界内(可能是在2字节读取处理器的结构中跟随char).

但这是不同的 - 我已经从堆/空闲存储请求内存,特别是请求的操作符new返回内存,该内存将保持与sizeof(T)对齐的元素.

总结一下这是TL; DR:

  • 是否可以在C++中对动态数组使用malloc()?
  • 是否可以在没有alignas关键字的旧C++中为动态数组使用operator new()和placement new?
  • 在运算符new()返回的内存上使用poiner算术未定义的行为?
  • Sutter建议代码哪些可能会破坏某些古董机器?

对不起,如果这是愚蠢的.

c++ arrays placement-new language-lawyer alignas

9
推荐指数
2
解决办法
307
查看次数

使用alignas语法苦苦挣扎

我正在尝试使用alignas作为类成员的指针,坦率地说,我不确定我应该把它放在哪里.

例如:

class A
{
private:
    int n;
    alignas(64) double* ptr;    

public:
    A(const int num) : n(num), ptr(new double[num])
    {}
};
Run Code Online (Sandbox Code Playgroud)

我希望能确保ptr的数据在64字节块上对齐.使用英特尔编译器,它没有.

有人能指出我正确的方向吗?

c++ icc c++11 alignas

8
推荐指数
1
解决办法
1069
查看次数

在32位平台上的结构中对齐

在为32位x86 linux运行以下代码时,我得到了意想不到的结果(编译器标志:g ++ -std = c ++ 14 -m32).我试过gcc和clang.

#include <iostream>
using namespace std;

struct S1
{
  uint64_t a;
  uint32_t b;
};

struct S2
{
  alignas(uint64_t) char a[8];
  uint32_t b;
};

int main()
{
  cout << "sizeof(S1)=" << sizeof(S1) << endl;
  cout << "sizeof(S2)=" << sizeof(S2) << endl;
}
Run Code Online (Sandbox Code Playgroud)

输出是:

sizeof(S1)=12
sizeof(S2)=16
Run Code Online (Sandbox Code Playgroud)

这里发生了什么?为什么S1和S2的尺寸不同?据我了解,64位整数值在32位x86机器上与32位对齐.这解释了为什么S1的大小是12个字节.但为什么这不适用于S2呢?

c++ padding alignas

8
推荐指数
1
解决办法
473
查看次数

alignas关键字未得到尊重

我想在缓存边界上输入我的类型,所以我使用了alignas:

struct alignas(64) W { };
Run Code Online (Sandbox Code Playgroud)

编译好了.但是,令我惊讶的是,当我尝试分配一堆Ws时,它们不是64字节对齐但实际上是16字节对齐的:

#include <iostream>
#include <iomanip>
#include <unordered_map>

struct alignas(64) W { };

int main() {
    std::unordered_map<int, int> offset;

    for (int i = 0; i < 1000; ++i) {
        auto w = new W;
        offset[(uintptr_t)w % 64]++;
    }   

    for (const auto& p : offset) {
        std::cout << p.first << ' ' << p.second << '\n';
    }   
}
Run Code Online (Sandbox Code Playgroud)

产量:

0 250
16 250
32 250
48 250
Run Code Online (Sandbox Code Playgroud)

几个编译(gcc 4.8.2,gcc 5.2.0,clang 3.7.1).这是怎么回事?我告诉它要对齐,为什么不对齐?

c++ c++11 alignas

6
推荐指数
1
解决办法
1102
查看次数

为什么在使用 clang 进行静态声明时,alignas 无法编译?

我在 clang 上遇到编译错误,并使用以下代码对 gcc 发出警告:

static alignas(16) int one_s = 1;                      // clang: error: an attribute list cannot appear here; gcc: warning: attribute ignored;
static __attribute__((aligned(16))) int zero_s = 0;    // on the other hand this works well on both compilers...
alignas(16) int one = 1;                               // this also works on both compilers
__attribute__((aligned(16))) int zero = 0;             // as well as this
Run Code Online (Sandbox Code Playgroud)

有谁知道为什么在包含 static 关键字的声明中不接受alignas?我将 --std=c++11 编译器选项与 gcc 和 clang 一起使用。(编辑:我使用 clang 3.4 及更高版本和 gcc 4.8 及更高版本)

请注意,使用 Visual …

c++ static clang language-lawyer alignas

5
推荐指数
1
解决办法
1304
查看次数

如何用 std::byte[] 替换aligned_storage&lt;T[]&gt;?

C++23 中已弃用的使用aligned_storage,建议用对齐方式替换std::byte[](请参阅此处)。我对此有两个问题:

1.如何对齐?

该文件建议更换

std::aligned_storage_t<sizeof(T), alignof(T)> t_buff;

alignas(T) std::byte t_buff[sizeof(T)]

然而,我实际上存储的是一个 T 数组(或者 T 是一个数组)。我可以简单地替换 std::aligned_storage_t<sizeof(T), alignof(T)> data_[SIZE];

alignas(alignof(T)*SIZE) std::byte data_[sizeof(T) * SIZE];

我认为这是错误的用法alignas吗?

2. 如何读/写?

我认为访问权限没有太大变化,因此阅读是否正确:

reference data(size_t index) noexcept {
    return *std::launder(reinterpret_cast<T*>(&data_[index*sizeof(T)]));
}
Run Code Online (Sandbox Code Playgroud)

并写与

new (reinterpret_cast<void*>(&data_[size_*sizeof(T)])) T{std::forward<Args>(args)...};

我为什么要问?

我的使用alignas似乎确实错误,我应该如何对齐它?我真的可以将访问索引与 相乘sizeof(T),还是需要考虑填充?如何?

另外,代码似乎比以前更糟糕,因为我必须sizeof()到处插入。

当我运行它时它似乎有效,但我不确定这是否真的保存。

我查看了其他示例(例如,此处此处和其他示例),但它们总是T以而不是T[]作为示例。

c++ alignas

5
推荐指数
1
解决办法
259
查看次数

alignas() 对 sizeof() 的影响 - 强制性的?

这个程序:

struct alignas(4) foo {};
int main() { return sizeof(foo); }
Run Code Online (Sandbox Code Playgroud)

返回 4,包含 GCC 10.1 和 clang 10.1,以及 icc 19.0.1。

这让我想知道 - 是否必须alignas()sizeof()这种方式影响?即增加超出结构最初大小的大小?或者 - 这种变化只是实现的特权吗?

c++ sizeof language-lawyer c++11 alignas

4
推荐指数
1
解决办法
127
查看次数

std :: alignas如何优化程序性能?

在32位计算机中,一个内存读取周期获取4 bytes个数据。
因此要读取下面的缓冲区,读取下面提到的128个缓冲区应该花费32个读周期bytes

char buffer[128];
Run Code Online (Sandbox Code Playgroud)

现在,假设如果我按如下所述对齐了该缓冲区,那么请让我知道它将如何使其更快地读取?

alignas(128) char buffer[128];
Run Code Online (Sandbox Code Playgroud)

我假设内存读取周期将仅保留4个字节。

c++ optimization c++11 alignas

3
推荐指数
1
解决办法
487
查看次数