Machine code footprint


When I compile the attached code, I find that one instantiation of vector::_M_fill_insert is double the size of the other even though the semantics should be the same:

$ clang++ -O3 -g -c insert.cpp
$ nm insert.o --size-sort -Ctd
0000000000000079 W std::vector<A, std::allocator<A> > f<A>()
0000000000000079 W std::vector<long, std::allocator<long> > f<long>()
0000000000001765 W std::vector<long, std::allocator<long> >::_M_fill_insert(__gnu_cxx::__normal_iterator<long*, std::vector<long, std::allocator<long> > >, unsigned long, long const&)
0000000000003638 W std::vector<A, std::allocator<A> >::_M_fill_insert(__gnu_cxx::__normal_iterator<A*, std::vector<A, std::allocator<A> > >, unsigned long, A const&)

What is the reason for this? I would expect that a class trivially containing one member would be treated the same as just the member.

I'm using clang 10 on Ubuntu 20.04.

Best regards,

insert.cpp (234 Bytes)

Looks like most of the difference can be accounted for by the fact that A is not default constructible - which probably causes some more complicated code in the standard library which the compiler isn’t currently able to see through. I haven’t looked at the specifics of what that might be:

$ cat vec.cpp



std::vector f()


std::vector a;

a.resize(10000, 1);

return a;


class A



long a;

A() = default;

A(long a) : a(a) {}


template std::vector f();

template std::vector f();

$ clang+±tot -O3 vec.cpp -c && nm vec.o --size-sort -Ctd

0000000000000079 W std::vector<A, std::allocator > f()

0000000000000079 W std::vector<long, std::allocator > f()

0000000000001802 W std::vector<A, std::allocator >::_M_fill_insert(__gnu_cxx::__normal_iterator<A*, std::vector<A, std::allocator > >, unsigned long, A const&)

0000000000001898 W std::vector<long, std::allocator >::_M_fill_insert(__gnu_cxx::__normal_iterator<long*, std::vector<long, std::allocator > >, unsigned long, long const&)