6

I want to have the number of milliseconds since epoch. A popular solution looks like follows (one of the solutions of this question asked here Get time since epoch in milliseconds, preferably using C++11 chrono )

#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;
}

compiling this with a call to g++ like g++ -std=c++11 main.cpp -o timetest results in the output

1372686001

which is equal to the number of seconds since epoch!

Is this a bug in the glibc? in g++? my mistake?

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

Update: it works when using the g++ 4.8. So it is a gcc bug?!

g++-4.8 (Debian 4.8.1-2) 4.8.1
Community
  • 1
  • 1
example
  • 3,349
  • 1
  • 20
  • 29
  • Works fine here: http://coliru.stacked-crooked.com/view?id=58cbeec8ffe15b00c4c5617e5c661e44-95b421f505320e75ab053309436f3288 – R. Martinho Fernandes Jul 01 '13 at 13:47
  • @R.MartinhoFernandes do you use the same g++ and glibc versions? – example Jul 01 '13 at 13:48
  • I edited the link to include the output of `g++ -v` (it's 4.8.1). Meaning that if it was a bug, it was fixed. – R. Martinho Fernandes Jul 01 '13 at 13:48
  • The code works correctly under [GCC 4.7.2](http://ideone.com/s4VM4w) – megabyte1024 Jul 01 '13 at 13:57
  • @R.MartinhoFernandes thanks for giving me the idea to use the g++ 4.8 `;)`. I will change g++ to point to version 4.8 per default - that should fix my problem. I don't know where yet, but maybe i should report this bug (as it seems rather certain now, that it is due to gcc v4.7.3) – example Jul 01 '13 at 14:04

1 Answers1

12

I think what's happening is that you are compiling with GCC 4.7 but the run-time linker is using the libstdc++.so from a different GCC version, and they are configured with different precision for std::chrono:system_clock. If you use LD_LIBRARY_PATH or suitable linker options to ensure you compile with GCC 4.7 and use its libstdc++.so then the results should be correct.

For example:

$ $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

The difference happens because the call to system_clock::now() is in the libstdc++.so library so the result depends on which library is used at run-time, but the duration_cast conversion from that value to milliseconds is done by inline templates which are instantiated at compile-time. If the compile-time conversion is not consistent with the run-time call then the results are inconsistent.

For GCC 4.8.1 the system_clock implementation was improved to always use the clock_gettime system call if it's available, which was not the case for 4.7, so it consistently uses the high-precision clock no matter how GCC was configured, which probably explains why you don't see the problem with 4.8.1.

You should always ensure the right version of libstdc++.so is used at run-time.

Jonathan Wakely
  • 166,810
  • 27
  • 341
  • 521
  • brilliant. so far I never had to pay attention to this (kind of annoying that it is necessary to be honest)... I would have expected that this is enough cause for a new version number (clearly the different versions of the libc are incompatible!) but well... thank you for clearing it up for me – example Jul 01 '13 at 16:30
  • 1
    In their default configurations the libraries are compatible, one of your compilers must have been built with `--enable-libstdcxx-time` which alters the library ABI, in which case it's your job to avoid mixing incompatible libraries. – Jonathan Wakely Jul 01 '13 at 17:02