2014-11-21 30 views
8

Trong khi tìm hiểu về các vấn đề liên kết vv, tôi nhận ra rằng việc triển khai g ++ 4.9 (macports OS X) không hỗ trợ cho std::align. Nếu tôi cố gắng biên dịch (với -std=c++11) mã ví dụ này từ http://www.cplusplus.com/reference/memory/align/std :: align không được hỗ trợ bởi g ++ 4.9

// align example 
#include <iostream> 
#include <memory> 

int main() { 
    char buffer[] = "------------------------"; 
    void * pt = buffer; 
    std::size_t space = sizeof(buffer) - 1; 
    while (std::align(alignof(int), sizeof(char), pt, space)) { 
    char* temp = static_cast<char*>(pt); 
    *temp = '*'; ++temp; space -= sizeof(char); 
    pt = temp; 
    } 
    std::cout << buffer << '\n'; 
    return 0; 
} 

trình biên dịch spits ra lỗi

error: 'align' is not a member of 'std' 

Điều này có vẻ kỳ lạ như g ++ dường như đã thực hiện hỗ trợ sự liên kết từ g ++ 4.8 , https://gcc.gnu.org/projects/cxx0x.html (N2341)

Mã biên dịch dưới dạng clang ++ mà không gặp bất kỳ sự cố nào.

Đây có phải là vấn đề nổi tiếng của g ++ mà tôi không biết? Các trình biên dịch trực tuyến mà tôi đã thử nghiệm (ideone và coliru) cũng từ chối mã đó.

Trả lời

12

Vâng, đây là một tính năng được biết đến thiếu cho gcc:

+0

Cảm ơn liên kết, chỉ thấy rằng nó không được tạo trong g ++ 4.9, mặc dù lỗi được báo cáo nhiều hơn hơn một năm trước. – vsoftco

+1

@vsoftco, "g ++ 4.9 trunk" không có ý nghĩa. Không có "g ++ 4.9 trunk". Có nhánh 4.9, và có thân cây, là một nhánh khác. Việc sửa chữa đã được thực hiện cho thân cây. Trường mục tiêu mốc trong báo cáo lỗi nói rằng nó sẽ được trong GCC 5.0 –

+0

@JonathanWakely cuối cùng đã nhận nó :) – vsoftco

2

Là một thay thế bạn có thể viết mã sự liên kết của riêng bạn mà phù hợp với hành vi của std::align. Đoạn mã tiếp theo được viết bởi David Krauss trong một bài đăng được tìm thấy tại đây: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=57350

inline void *align(std::size_t alignment, std::size_t size, 
       void *&ptr, std::size_t &space) { 
    std::uintptr_t pn = reinterpret_cast<std::uintptr_t>(ptr); 
    std::uintptr_t aligned = (pn + alignment - 1) & - alignment; 
    std::size_t padding = aligned - pn; 
    if (space < size + padding) return nullptr; 
    space -= padding; 
    return ptr = reinterpret_cast< void * >(aligned); 
} 
+1

Hãy coi chừng rằng dòng 'auto new_space = space - (aligned - pn);' là một tiềm ẩn unsigned underflow. Liên kết được đề cập cũng cung cấp phiên bản đã sửa. – Kemal

Các vấn đề liên quan