使用 MSVC

时间:2021-02-08 14:12:24

标签: c++ visual-c++ compiler-errors cuda compiler-bug

在我的一个库中,我有以下代码(为简洁起见):

namespace memory {
namespace managed {

namespace detail {

template <typename T>
inline T get_scalar_range_attribute(
    region_t region,
    cudaMemRangeAttribute attribute)
{ /* snip */ }

} // namespace detail

struct region_t : public memory::region_t {
    // snip
    bool is_read_mostly() const
    {
        return detail::get_scalar_range_attribute<bool>(
            *this, cudaMemRangeAttributeReadMostly);
    }

    // snip
}

} // namespace managed
} // namespace memory

现在,在 Linux 上使用 GCC 和 Clang,这可以正常工作。但是对于 Windows 上的 MSVC 16.8.4,我的一个用户得到:

error : template instantiation resulted in unexpected function type of "__nv_bool
(cuda::memory::managed::region_t, cudaMemRangeAttribute)" (the meaning of a name
may have changed since the template declaration -- the type of the template is "T
(cuda::memory::region_t, cudaMemRangeAttribute)"

我不明白实例化如何导致意想不到的事情,永远。我也没有看到我的一个类名与另一个类名的“名称隐藏”应该如何对模板实例化产生任何影响。

1 个答案:

答案 0 :(得分:1)

(大部分内容归功于@Guillaume Racicot。)

这里的问题是名称查找的时间。

其他编译,当遇到模板声明region_t时,似乎寻找之前定义的region_t;找到memory::region_t;没关系。 (如果我错了,请纠正我)。

然而,MSVC 执行两次查找:一次是在遇到声明+定义时,然后是在实例化时 - 两次都使用不同的上下文。所以,它第一次找到 memory::region_t;第二次找到memory::managed::region_t。这是“意外”...

MSVC 的这种行为显然是由于其“许可”编译模式(默认情况下启用)。这有点奇怪,看看在这种情况下它是如何不太宽容的,但事实就是如此。

相关问题