2013-04-30 19 views
3

考虑下面的代码:使用率问题::对准

#include <memory> 
#include <iostream> 
#include <cstdio> 

using namespace std; 

// Visual Studio 2012 don't have alignof as a keyword. 
#define alignof(type) __alignof(type) 

#define TEST_TYPE int 

int main(int, char*[]) 
{ 
    TEST_TYPE i; 
    void* pv = &i; 
    size_t space = 100; // Just some big number. 

    size_t alignment = alignof(TEST_TYPE); 

    cout << "Alignment of int: " << alignment << endl; 
    cout << "Is 'i' aligned: " 
     << (size_t(&i) % alignment == 0 ? "true" : "false") 
     << endl; 

    if (align(alignment, sizeof(TEST_TYPE), pv, space)) 
    { 
     TEST_TYPE* p = reinterpret_cast<TEST_TYPE*>(pv); 

     cout << "Moved pointer " 
      << (size_t(p) - size_t(&i)) 
      << " bytes" 
      << endl; 

     cout << "Is 'p' aligned: " 
      << (size_t(p) % alignment == 0 ? "true" : "false") 
      << endl; 
    } 
    else 
    { 
     cout << "Can't align 'i'" << endl; 
    } 

    return 0; 
} 

它创建了一个(正确对齐)整数,然后调用的std ::与整数的地址一致。我得到的输出是:

INT的对齐:4
是 'I' 对齐:
移到真实指针4个字节
对齐 'P':真

指示指针移动即使地址已经正确对齐。但是,文档(http://en.cppreference.com/w/cpp/memory/align)说它“...修改ptr以指向这种对齐的存储的第一个可能的地址...”但是这不会意味着指针应该保持不变吗?

所以我的问题:如果参数指针已经对齐,std :: align(指针)的第三个参数是否总是会更改为一个大小更大?

编辑

此外,如果指针不那么改变不会http://www.cplusplus.com/reference/memory/align/?kw=align的例子进入无限循环?

第二编辑

注意链接已被更新和可能出现的问题不再出现。

+0

来自clang ++/libC++的输出是'Moved pointer 0 bytes' – Cubbi 2013-04-30 17:15:31

+0

如果我将pv指针更改为&i - 1个字节(做一些快速转换),指针将移动11个字节。 这是一个编译器错误吗? – 2013-04-30 17:20:41

+0

(意思是5个字节,在宏中有一个不同的类型)。 – 2013-04-30 17:26:20

回答

2

这就像在你的标准库实现中的错误,输出应该是“感动指针为0字节”作为pv已经对齐,所以在范围[pv,pv+100)第一个正确对齐的地址,是pv本身,而不是pv+4

虽然它说,在标准:

功能更新其PTR和空间参数,以便它可以反复用 可能不同的定位和尺寸参数调用同一个缓冲区

我不确定这是什么意思,或者它是否相关。我不认为这是。

+0

看看VS11中的实现,它确实看起来不正确。第二个链接上的示例如何?如果对齐可以让指针独立,如果它已经对齐,是不是循环缺少指针的增量? – 2013-05-01 10:38:28

+0

@JensÅkerblom:哪个链接对不起? – 2013-05-01 11:50:09

+0

“编辑”后的一个:http://www.cplusplus.com/reference/memory/align/?kw=align – 2013-05-01 12:02:24