2013-07-01 36 views
5

Tôi muốn có số mili giây từ thời đại. Một giải pháp phổ biến trông giống như sau (một trong những giải pháp của câu hỏi này hỏi đây Get time since epoch in milliseconds, preferably using C++11 chrono)C++ chrono duration_cast đến mili giây cho kết quả tính bằng giây

#include <iostream> 
#include <chrono> 

int main() { 
    auto millitime = std::chrono::duration_cast<std::chrono::milliseconds> 
     (std::chrono::system_clock::now().time_since_epoch()).count(); 
    std::cout << millitime << std::endl; 
    return 0; 
} 

biên dịch này với một cuộc gọi đến g++ như g++ -std=c++11 main.cpp -o timetest kết quả ở đầu ra

1372686001 

đó là tương đương với số lượng giây từ thời đại!

Đây có phải là lỗi trong glibc không? trong g ++? lỗi của tôi?

g++ (Debian 4.7.3-4) 4.7.3 
ldd (Debian EGLIBC 2.17-6) 2.17 

Cập nhật: nó hoạt động khi sử dụng g ++ 4.8. Vì vậy, nó là một lỗi gcc ?!

g++-4.8 (Debian 4.8.1-2) 4.8.1 
+0

Hoạt động tốt ở đây: http://coliru.stacked-crooked.com/view?id=58cbeec8ffe15b00c4c5617e5c661e44-95b421f505320e75ab053309436f3288 –

+0

@ R.MartinhoFernandes bạn có sử dụng cùng phiên bản g ++ và glibc không? – example

+0

Tôi đã chỉnh sửa liên kết để bao gồm đầu ra của 'g ++ -v' (là 4.8.1). Có nghĩa là nếu nó là một lỗi, nó đã được sửa. –

Trả lời

11

Tôi nghĩ rằng những gì đang xảy ra là bạn đang biên soạn với GCC 4.7 nhưng thời gian chạy mối liên kết được sử dụng libstdc++.so từ một phiên bản GCC khác nhau, và chúng được cấu hình với độ chính xác khác nhau cho std::chrono:system_clock. Nếu bạn sử dụng LD_LIBRARY_PATH hoặc tùy chọn trình liên kết phù hợp để đảm bảo bạn biên dịch với GCC 4.7 sử dụng số libstdc++.so thì kết quả sẽ chính xác.

Ví dụ:

$ $HOME/gcc/4.7.1/bin/g++ -std=c++11 t.cc 
$ ./a.out 
1372693222 
$ LD_LIBRARY_PATH=$HOME/gcc/4.7.1/lib64 ./a.out 
1372693225128 

Sự khác biệt xảy ra vì cuộc gọi đến system_clock::now() là trong thư viện libstdc++.so nên kết quả phụ thuộc vào thư viện được sử dụng tại thời gian chạy, nhưng duration_cast chuyển đổi từ giá trị đó milliseconds được thực hiện bởi các mẫu nội tuyến được khởi tạo tại thời gian biên dịch. Nếu quá trình biên dịch thời gian không nhất quán với cuộc gọi thời gian chạy thì kết quả sẽ không phù hợp.

Đối với GCC 4.8.1 việc thực hiện system_clock được cải thiện để luôn sử dụng cuộc gọi hệ thống clock_gettime nếu có, không phải là trường hợp 4.7, do đó nó luôn sử dụng đồng hồ có độ chính xác cao bất kể cấu hình GCC như thế nào có thể giải thích tại sao bạn không thấy vấn đề với 4.8.1.

Bạn nên luôn đảm bảo phiên bản phù hợp của libstdc++.so được sử dụng trong thời gian chạy.

+0

rực rỡ. cho đến nay tôi không bao giờ phải chú ý đến điều này (loại khó chịu mà nó là cần thiết phải trung thực) ... Tôi đã có thể mong đợi rằng điều này là đủ nguyên nhân cho một số phiên bản mới (rõ ràng các phiên bản khác nhau của libc là không tương thích!) nhưng cũng ...Cảm ơn bạn đã xóa nó cho tôi – example

+1

Trong cấu hình mặc định của chúng, các thư viện tương thích, một trong các trình biên dịch của bạn phải được xây dựng với '--enable-libstdcxx-time' làm thay đổi thư viện ABI, trong trường hợp đó là công việc của bạn để tránh trộn các thư viện không tương thích. –

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