Default value of function parameter initialized by list initialization
Asked Answered
R

2

19

Could anyone help me with the following problem?

There is a simple code:

#include <vector>

struct A {
    std::vector<int> vec;
};

void func (A &&a = {}) {}

int main()
{
    func();
    return 0;
}

When I try to compile it by gcc 5.4.0 I get the error:

undefined reference to `std::vector<int, std::allocator<int> >::vector()'

Amazingly, but clang compiles it well. Also if to modify the code a little bit it is compiled without any problems:

#include <vector>

struct A {
    std::vector<int> vec;
};

void func (A &&a) {}

int main()
{
    func({});
    return 0;
}

I really cann't understand what's wrong with the first code.

Ramberg answered 16/6, 2017 at 11:29 Comment(14)
Could you provide command line you use for compiling? Are you using g++?Fugazy
I tried gcc 6.3.0 with the same result. Only clang works well as I mentioned.Aggravation
@NathanOliver , it seems that my description was a bit misleading. Object file will be compiled well but when you start linkage to get binary you'll get the same issue. You can see it also with online compiler you reffered. Just push "Compile to binary".Aggravation
Are you using by any chance some self-installed gcc on Mac OSX? I could reproduce your error on my mac book with a homebrew installation of gcc 6.2.0 that was somehow compromised (and also produced several warnings in the compilation process itself).Leshia
Oh, wow. Tried here and got the same results.Starflower
@MarekVitek , the command is simple: $ g++ -std=c++11 -o main.x main.cpp /tmp/ccoaMpv0.o: In function main': main.cpp:(.text+0x1b): undefined reference to std::vector<int, std::allocator<int> >::vector()' collect2: error: ld returned 1 exit statusAggravation
Reproduced on Wandbox: wandbox.org/permlink/iLVJFtVkCWebXntD.Cretaceous
Looks like you've uncovered a bug of gcc. You should report it. The strange thing is that the missing symbol is generated from a template and hence fully inline. The compiler should have generated that, rather than asking the linker to load it.Leshia
Might be the same cause as this bug reportStarflower
I was looking in wrong direction. This might be some issue with gcc. I have maybe interesting note, I tried to add following line ` A && x = {};` between call to func and return. Suddenly it compiles without eror.Fugazy
Same problem if you replace vector with list (or any other templated container I suppose).Leshia
@Starflower That is indeed the answer. Please write it up.Leshia
It's acctualy not a vector problem: wandbox.org/permlink/7ZZrMnzOUX6hdOxbBromo
@Black Moses yes it is not problem with vector. It is problem with instantiation of template in this specific scenario. See my Answer with code example.Fugazy
S
11

This is a gcc bug. It can also be reproduced with

template<typename Value>
struct A
{
    A() = default;
    std::vector<Value> m_content;
};

void func(A<int> a = {})
{
}

int main()
{
    func();
}

Currently though, there is no status on it.

I appears that the lack of an actual instance of the vector is causing the compiler to not stamp out the code for it which leads to the undefined reference.

Starflower answered 16/6, 2017 at 12:29 Comment(0)
F
3

As @NathanOliver mentioned, this is a GCC bug. What is the bug? It seems to me that it forgets to instantiate a class std::vector<int> when it is used as a function parameter and enclosed in another type.
You can work around it by using A somewhere else in the code. Even a simple declaration is enough. It forces the compiler to instantiate the templated type and you are good. Look for A unused in the code below that will compile.

#include <vector>

struct A {
    std::vector<int> vec;
};

void func (A &&a = {}) {
    A unused;
}

int main()
{
    func();
    return 0;
}
Fugazy answered 16/6, 2017 at 13:3 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.