boostorg / boostorg/rational

Abstract Base By Reference Canidate Causing Errors

Open
#34 7 comments 0 reactions 0 assignees View on GitHub
Dominant language
C++
Stars
24
Forks
45
PR merge metrics
No merged PRs in 30d

Description

Please consider this sample code:
```cpp
#include
#include

class AbstractBase
{
public:
virtual ~AbstractBase() {}
virtual int MethodToMakeBaseAbstract() const = 0;
};
class Derived : public AbstractBase
{
public:
int MethodToMakeBaseAbstract() const override { return 0; }
};

int FramesToSeconds( const AbstractBase& /*project*/ )
{
return 3;
}
int FramesToSeconds( boost::rational /*editRate*/ )
{
return 4;
}

int main()
{
AbstractBase* p = new Derived();

std::cout << FramesToSeconds( *p ) << std::endl;

delete p;
}
```

I believe the output should be `3` and with no problems compiling. It compiles fine on Clang. I am having issues with GCC (9.0.1.201902) and Microsoft Visual Studio 15.7.5 with Boost version 1.64.0 and higher (tested through Boost version 1.69.0). Boost version 1.63.0 seems builds fine with that example on GCC.

Here is the compiler flags with using [Wandbox](https://wandbox.org/) to test this
```
g++ prog.cc -Wall -Wextra -I/opt/wandbox/boost-1.64.0/gcc-head/include -std=c++17
```

Here are the errors I am seeing:

```
In file included from /opt/wandbox/gcc-head/include/c++/9.0.1/string_view:40,
from /opt/wandbox/gcc-head/include/c++/9.0.1/bits/basic_string.h:48,
from /opt/wandbox/gcc-head/include/c++/9.0.1/string:55,
from /opt/wandbox/gcc-head/include/c++/9.0.1/bits/locale_classes.h:40,
from /opt/wandbox/gcc-head/include/c++/9.0.1/bits/ios_base.h:41,
from /opt/wandbox/gcc-head/include/c++/9.0.1/iomanip:40,
from /opt/wandbox/boost-1.64.0/gcc-head/include/boost/rational.hpp:68,
from prog.cc:1:
/opt/wandbox/gcc-head/include/c++/9.0.1/limits: In instantiation of 'struct std::numeric_limits':
/opt/wandbox/boost-1.64.0/gcc-head/include/boost/rational.hpp:119:7: required from 'const bool boost::rational_detail::is_compatible_integer::value'
/opt/wandbox/boost-1.64.0/gcc-head/include/boost/rational.hpp:156:21: required by substitution of 'template constexpr boost::rational::rational(const T&, const typename boost::enable_if_c::value, void>::type*) [with T = AbstractBase]'
prog.cc:29:37: required from here
/opt/wandbox/gcc-head/include/c++/9.0.1/limits:317:7: error: invalid abstract return type 'AbstractBase'
317 | min() _GLIBCXX_USE_NOEXCEPT { return _Tp(); }
| ^~~
prog.cc:4:7: note: because the following virtual functions are pure within 'AbstractBase':
4 | class AbstractBase
| ^~~~~~~~~~~~
prog.cc:8:16: note: 'virtual int AbstractBase::MethodToMakeBaseAbstract() const'
8 | virtual int MethodToMakeBaseAbstract() const = 0;
| ^~~~~~~~~~~~~~~~~~~~~~~~
In file included from /opt/wandbox/gcc-head/include/c++/9.0.1/string_view:40,
from /opt/wandbox/gcc-head/include/c++/9.0.1/bits/basic_string.h:48,
from /opt/wandbox/gcc-head/include/c++/9.0.1/string:55,
from /opt/wandbox/gcc-head/include/c++/9.0.1/bits/locale_classes.h:40,
from /opt/wandbox/gcc-head/include/c++/9.0.1/bits/ios_base.h:41,
from /opt/wandbox/gcc-head/include/c++/9.0.1/iomanip:40,
from /opt/wandbox/boost-1.64.0/gcc-head/include/boost/rational.hpp:68,
from prog.cc:1:
/opt/wandbox/gcc-head/include/c++/9.0.1/limits:321:7: error: invalid abstract return type 'AbstractBase'
321 | max() _GLIBCXX_USE_NOEXCEPT { return _Tp(); }
| ^~~
/opt/wandbox/gcc-head/include/c++/9.0.1/limits:327:7: error: invalid abstract return type 'AbstractBase'
327 | lowest() noexcept { return _Tp(); }
| ^~~~~~
/opt/wandbox/gcc-head/include/c++/9.0.1/limits:333:7: error: invalid abstract return type 'AbstractBase'
333 | epsilon() _GLIBCXX_USE_NOEXCEPT { return _Tp(); }
| ^~~~~~~
/opt/wandbox/gcc-head/include/c++/9.0.1/limits:337:7: error: invalid abstract return type 'AbstractBase'
337 | round_error() _GLIBCXX_USE_NOEXCEPT { return _Tp(); }
| ^~~~~~~~~~~
/opt/wandbox/gcc-head/include/c++/9.0.1/limits:341:7: error: invalid abstract return type 'AbstractBase'
341 | infinity() _GLIBCXX_USE_NOEXCEPT { return _Tp(); }
| ^~~~~~~~
/opt/wandbox/gcc-head/include/c++/9.0.1/limits:346:7: error: invalid abstract return type 'AbstractBase'
346 | quiet_NaN() _GLIBCXX_USE_NOEXCEPT { return _Tp(); }
| ^~~~~~~~~
/opt/wandbox/gcc-head/include/c++/9.0.1/limits:351:7: error: invalid abstract return type 'AbstractBase'
351 | signaling_NaN() _GLIBCXX_USE_NOEXCEPT { return _Tp(); }
| ^~~~~~~~~~~~~
/opt/wandbox/gcc-head/include/c++/9.0.1/limits:357:7: error: invalid abstract return type 'AbstractBase'
357 | denorm_min() _GLIBCXX_USE_NOEXCEPT { return _Tp(); }
| ^~~~~~~~~~
```

There are several workarounds I can do to get my code to compile such as make the `AbstractBase` class not be abstract (no pure virtual functions), or rename the function so it is no longer considered, and also make my function take the base class by pointer instead of reference. Because it builds on Clang, I am not sure if it is ultimately a GCC/MSVC bug.

Let me know if there is any additional information I can give you to help. Thank you.

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.