2017-08-16 17 views
28

Khi một thành viên tĩnh trong một lớp C++ là cả hai thread_local và mẫu thành viên, nó không được khởi tạo.thread_local tĩnh mẫu thành viên định nghĩa: initialisation thất bại với gcc

#include <unordered_map> 
#include <iostream> 

class A { 
public: 
    template<typename T> 
    thread_local static std::unordered_map<int,T> m; 
}; 

template<typename T> 
thread_local std::unordered_map<int,T> A::m{}; 

int main() { 
    // A::m<int> = std::unordered_map<int,int>{}; // solves the problem 
    std::cout << A::m<int>.bucket_count() << std::endl; // returns zero. 
    A::m<int>.insert({1,2}); // causes SIGPFE (hash modulo bucket_count) 
} 

Unordered_map không được khởi tạo và có tổng số lượng là 0. Điều này dẫn đến một bộ phận zero khi băm được lấy modulo số lượng xô. Nếu không có thread_local hoặc không có các template nó hoạt động tốt. Khởi tạo thành viên theo cách thủ công trong mỗi chuỗi sử dụng nó (dòng nhận xét) giải quyết được vấn đề.

Hành vi không xác định này theo tiêu chuẩn C++ hay đây có thể là lỗi trình biên dịch không? Tôi đã thử với gcc 7.1.1 và với 5.2.0 mà cả hai đều tạo ra lỗi. clang 3.8 dường như hoạt động.

Edit: Tôi khẳng định hành vi này với gcc 8.0.0 20.170.817 từ SVN và đệ trình một báo cáo lỗi: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81880

+3

Có vẻ như một lỗi rõ ràng với tôi. Bạn có gửi báo cáo lỗi không? Nếu bạn đã làm, bạn có thể vui lòng chia sẻ liên kết? – SergeyA

+0

gcc (HEAD) 8 ... bị ảnh hưởng bởi điều này quá – Swift

+1

Tôi không nghĩ đó là lỗi. Tại sao ứng dụng của bạn lãng phí thời gian khởi tạo dữ liệu cho mỗi chuỗi bạn tạo ngay cả khi nó sẽ không sử dụng nó? Thread-local storage được xử lý bởi hệ điều hành, chứ không phải bởi trình biên dịch. –

Trả lời

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