Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing abstract object by value weirdness in clang++

Tags:

c++

why does clang++ 3.6 compile the follwing code (g++ doesn't)?

class Abc
{
public:
    virtual void foo() const = 0;
    virtual ~Abc() {}
};

// is correctly rejected
// void bar(Abc o)
// {
// }

class B
{
    void bar(Abc o) // should also be rejected
    {
    }

};

int main()
{
}

I am using clang 3.6 and gcc 4.9.2.

Why is the free function (correctly) rejected and the member function not?

Any hints? A Bug in clang?

If I modify the above to:

class Abc
{
public:
    virtual void foo() const = 0;
    virtual ~Abc() {}
};
class Impl : public Abc {
public:
    void foo() const {}
};
class B
{
public:
    void bar(Abc o)
    {
        o.foo();
    }
};
int main()
{
    B b;
    Impl i;
    b.bar(i);
}

I get an

main.cc:16: undefined reference to `Abc::foo() const'

linker error.

So the question is: why at all allows clang++ to compile this wrong code? I would say that is a heavy bug!

like image 201
wimalopaan Avatar asked Mar 27 '15 07:03

wimalopaan


1 Answers

As N4296 10.4 [class.abstract] says:

An abstract class shall not be used as a parameter type, as a function return type, or as the type of an explicit conversion. Pointers and references to an abstract class can be declared.

[ Example:
shape x;//  error: object of abstract class
shape* p;// OK
shape f();// error
void g(shape);// error
shape& h(shape&);//OK
— end example ]

So gcc follow the standard.

Why cannot declare parameter to be of abstract type? Suppose when a pass subclass object to bar,object slicing happen,oh,an object that has a pure virtual function...This is a contradiction.That maybe the reason.

EDIT:

Why clang pass it,it is clang compiler issue.

like image 187
Ron Tang Avatar answered Oct 08 '22 03:10

Ron Tang