Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Is there any obvious way to rewrite this code to work around a compiler bug triggering invalid C2244 error?

The following is valid, standard-conforming code from the GCC source code base. It trips the Visual C++ compilers, triggering error C2244. That is a compiler bug that I already reported, but it’s unlikely to get solved soon. Too low of an impact they say. Now, I’d be rather miffed if my compiler product choked on a leading open-source compiler codebase, but that’s just me.

Is there some workaround or a way to rewrite this to preserve the API while getting it past VS C++?

Getting the function body inside the class declaration works around the issue, but that’s a bit of a stylistic nightmare and has about zero chance of upstreaming. So I was hoping for something less drastic.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

Error:

(17): error C2244: ‘hash_table::traverse_noresize’: unable to match function definition to an existing declaration

Self-contained repro case below – also available on Godbolt. No compile flags needed, and AFAIK it trips all releases of VS 2022.

// minimized excerpt from gcc/hash_table.h

template <class Descriptor> class hash_table
{
  using value_type = typename Descriptor::value_type;
public:
  template <int (*Callback)(value_type *)> void traverse_noresize ();
};

template<class Descriptor>
template<int (*Callback) (typename hash_table<Descriptor>::value_type *)>
void hash_table<Descriptor>::traverse_noresize() {}
// Error C2244 in line above. Apparently, this definition doesn't match the declaration
// in the class body.

struct D { using value_type = int; };
int C(int *slot) { return {}; }

void test()
{
    hash_table<D> ht;
    ht.traverse_noresize<C>();
}

>Solution :

The problem is that MSVC is resolving the alias hash_table<...>::value_type early, and then failing to resolve it during member function (template) declaration matching. Manually dealiasing at the definition appears to work:

template<typename Descriptor>
template<typename Argument,
     int (*Callback)
     (typename Descriptor::value_type *slot,
//             ^~~~~~~~~~
     Argument argument)>
void hash_table<Descriptor>::traverse_noresize () {}

Demo.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading