c++c++17gcc8

vector must have the same value as its allocator


This MCVE compiles/runs with gcc 7.3:
Please note, this MCVE has been dramatically reduced keeping the error reproduce able, so the code in the Allocator template doesn't make sense but it doesn't affect the constallation!

#include <regex>
#include <string>
#include <iostream>

namespace FaF
{
    template <typename T>
    class Allocator
    {
        public:
            typedef T value_type;

            Allocator() throw() {}
            template <typename U> Allocator (const Allocator<U>&) throw() {}
            ~Allocator() throw() {}

            T* allocate (std::size_t num, const void* hint = 0)
            {
                (void) hint; (void) num;
                return  new ( T );
            }

            void deallocate (T* p, std::size_t num) { (void) num; (void) p; }
    };

    using string = std::basic_string<char, std::char_traits<char>, Allocator<char>>;
    using smatch = std::match_results<FaF::string::const_iterator, Allocator<FaF::string::const_iterator>>;
}

int main()
{
    FaF::smatch results {};
    std::cout << "OK\n";
}

where Allocator is my own allocator.

We are now using gcc 8.2 and get this error

    FaF::smatch results {};
    ^--- vector must have the same value as its allocator

When I change FaF::smatch to the default std::smatch then it compiles/runs with gcc 8.2.

My question:

What is the reason and why this code doesn't compile with gcc 8.2 even it did with gcc 7.3 with C++17 setting - nothing else changed. This is what confuses me. Somewhere changed something which doesn't have apparently to do anything with C++.

See it live - clang 6.0 accepts the version with FaF::smatch as well.

Compiler flags:
-O3 -std=c++17 -Werror -Wextra -Wold-style-cast -Wall


Solution

  • I filed this case in the gnu gcc bug database and the solution is this:

    using smatch = std::match_results<FaF::string::const_iterator, 
          Allocator<std::sub_match<FaF::string::const_iterator>>>;
                    ^^^^^^^^^^^^^^^
    

    Here the answer from the gnu bug database link:

    The value type of match_result<Iter> is sub_match<Iter>, 
      so you need to use Allocator<sub_match<Iter>> not Allocator<Iter>.
    
    > Changing it to std::smatch then it compiles.
    
    
    Because that uses the correct allocator type.
    
    > Compiler options:
    > -O3 -std=c++17 -Werror -Wextra -Wold-style-cast -Wall
    
    
    If you use -std=gnu++17 then your code will be accepted,
      but is not portable and is not valid C++.
    

    I want to thank the gnu team for the very fast reply which helps also the SO community!