managarm / frigg

Lightweight C++ utilities and algorithms for system programming
MIT License
56 stars 20 forks source link

Incorrect cv-qualifier for return type of `array::data() const` #55

Closed davidtranhq closed 1 year ago

davidtranhq commented 1 year ago

The following program fails to compile:

#include <frg/array.hpp>

class ConstArrayTest 
{
public:
    const int *data() const
    {
        return arr_.data();
    }

private:
    frg::array<int, 5> arr_;
};

ConstArrayTest<int> t;
include/frg/array.hpp:74:30: error: invalid conversion from ‘const value_type*’ {aka ‘const int*’} to ‘int*’ [-fpermissive]
   74 |                 return &_stor[0];
      |                         ~~~~~^
      |                              |
      |                              const value_type* {aka const int*}

This seems to be because in array.hpp the return type of array::data() const is marked constexpr but not const (constexpr makes the pointer type const, but not the pointed-to value).

 constexpr T* data() const noexcept {
//         ^
//         |
//         should be constexpr const T*!
    return &_stor[0];
}

I'm not sure why it works when templated, though.

// compiles no problem

template <typename T>
class ConstArrayTest 
{
public:
    const T *data() const
    {
        return arr_.data();
    }

private:
    frg::array<T, 5> arr_;
};

ConstArrayTest<int> t;

Both examples compile with the GNU implementation of the C++ Standard Library, which does declare the return type const:

_GLIBCXX17_CONSTEXPR const_pointer
data() const noexcept
{ return _AT_Type::_S_ptr(_M_elems); }