1

I was wondering if there's any tool in GNU or LLVM toolchains that can help to get the c++ version info from a object or library?

cartman
  • 732
  • 2
  • 8
  • 20
  • **Related:** [GCC ABI compatibility](https://stackoverflow.com/q/2801938/430766). – bitmask Aug 25 '20 at 08:17
  • C++ version of what? Of the source code from which the object/library file has been generated? Of the enabled implementation (compiler/standard library) support during compilation? Why is it important to know? – Daniel Langr Aug 25 '20 at 08:18
  • Sorry for not write it clearly, what I mean is the c++ standard version, like c++11, c++14, c++17, etc. It is important to know such inform of a third-party library when building an image with it. – cartman Aug 25 '20 at 08:21
  • 1
    @cartman uh.. in general.. no? unless library uses public definitions that vary that much depending on standard so it would cause ODR breach. But then, it mean library got an improper design. And do you mean static or shared library? – Swift - Friday Pie Aug 25 '20 at 08:22
  • 2
    An object is a bunch of machine instructions. There is no C++ in it, of any version. The C++ standard covers C++ *source programs*. – n. m. could be an AI Aug 25 '20 at 08:25
  • @n.'pronouns'm. it's not just bunch of machine instructions. It's in ELF format with some build attributes tags. But unfortunately, it seems the tags don't include c++ version. – cartman Aug 25 '20 at 08:26
  • Is such a library/object file accompanied with header files? Still does not understand what C++ Standard version matters for binary files. How is it related to the generated assembly? – Daniel Langr Aug 25 '20 at 08:26
  • @cartman then you talk about shared library (so called shared object, .so). .o file isn't ELF, and .lib is just an archive of .o files. In case of shared library it got dependencies, exported and imported symbols can be inspected by a number of tools, versions of dependencies can be seen, but not version of C++ used to compile it . calling conventions in library should match ABI. That's true for Linux and alike at least. Windows platform kinda different, because of SxS run-times – Swift - Friday Pie Aug 25 '20 at 08:32
  • @Swift-FridayPie .o, .a and .lib they are all in ELF format. Plese check out this: https://refspecs.linuxbase.org/elf/gabi4+/ch4.intro.html. If it's just bunch of assemble code, how to figure out the symbol, debug info, etc. from object file? – cartman Aug 25 '20 at 08:36
  • Compile a trivial C++ source file three times, with different -std flags, and binary-compare the objects. Do you see any difference? – n. m. could be an AI Aug 25 '20 at 08:43
  • 1
    @cartman .o is relocable.elf (note, _relocable_), .lib is not. it's an archive. But .o files have only tables that references to external symbols and assembly code, nothing can say about what standard was used – Swift - Friday Pie Aug 25 '20 at 08:45
  • You could do that by looking for DWARF info that relates to header files present only in newer C++ versions. – arnt Aug 30 '20 at 20:32

1 Answers1

3

I've just made a test with a simple .o file containing the compiled version of the following code:

#include <iostream>

void test()
{
    std::cout << "Hello\n";
}

I compiled it using the command:

for std in 03 11 14 17; do g++ test.cpp -std=c++$std -c -o test$std.o; done

Now I checked SHA1 sums of the resulting object files

$ sha1sum test*.o
f4805c820db889327a90c823f3515baed1f443dc  test03.o
2437e0d7aaf2dcf0575eff1237cad70ebef06448  test11.o
2437e0d7aaf2dcf0575eff1237cad70ebef06448  test14.o
f4805c820db889327a90c823f3515baed1f443dc  test17.o

As you can see, the object files for C++03 vs C++17, as well as for C++11 vs C++14, are identical. Thus there's no general way to distinguish between these, unless your code is compiled with some special options (of which I'm unaware).

bitmask
  • 32,434
  • 14
  • 99
  • 159
Ruslan
  • 18,162
  • 8
  • 67
  • 136
  • 1
    Although interesting, this doesn't mean that it will work for every compilation unit, especially more complicated ones. The fact that C++03 and C++17 produce the same, while being distinct from C++11 and C++14 should be a hint that this method is unreliable. – bitmask Aug 25 '20 at 09:13
  • @bitmask that's exactly the point of the answer: the mere existence of identical results already tells that there's no general method to distinguish between the standards having just the object files. – Ruslan Aug 25 '20 at 09:19
  • When I tried with clang++ 6.0, all 4 versions have the same hash – phuclv Aug 25 '20 at 10:03