c++gccconstants

GCC 14 update, operator= now complains about a read-only member?


I'm using a header-only raytracing library, NanoRT.

Within that file there is a class TriangleSAHPred. It has the following members:

  mutable int axis_;
  mutable T pos_;
  const T* vertices_;
  const unsigned int* faces_;
  const size_t vertex_stride_bytes_;

It also has an overload for operator=:

  TriangleSAHPred<T>& operator=(const TriangleSAHPred<T>& rhs)
  {
    axis_ = rhs.axis_;
    pos_ = rhs.pos_;
    vertices_ = rhs.vertices_;
    faces_ = rhs.faces_;
    vertex_stride_bytes_ = rhs.vertex_stride_bytes_;

    return (*this);
  }

This overload worked fine despite vertices_, faces_ and vertex_stride_bytes_ all being const.

However, as of GCC 14, this no longer works. Specifically, vertex_stride_bytes_ is a problem - the other two const members appear fine. I'd assume it's because those two are pointers, while vertex_stride_bytes_ is of type size_t.

My question: What changed in GCC14 that is causing this to break now after several years of working fine? Was it always wrong, or is something in the version of GCC14.1 I'm using wrong? Why does only vertex_stride_bytes_ cause an issue?


Solution

  • Here's a smaller example that reproduces this behaviour:

    https://godbolt.org/z/vYrefnPYs

    template<typename T>
    struct TriangleSAHPred
    {
      const int vertex_stride_bytes_;
      TriangleSAHPred<T>& operator=(const TriangleSAHPred<T>& rhs)
      {
        vertex_stride_bytes_ = rhs.vertex_stride_bytes_;
    
        return (*this);
      }
    };
    

    There is no template parameter T for which the definition for operator= would compile, since vertex_stride_bytes_ = rhs.vertex_stride_bytes_; does not depend on a template parameter and doesn't compile. This is formally "ill-formed no diagnostic required", meaning the program is invalid but a compiler doesn't have to tell you.

    GCC 13 just accepted this, but would error if you ever tried to use operator=. GCC 14 is smarter and is able to see that vertex_stride_bytes_ = rhs.vertex_stride_bytes_; is not dependendent on any template parameters and can't compile, so issues a diagnostic as it's parsing the template (before any TriangleSAHPred<T> for any T are instantiated).