【发布时间】:2021-05-07 01:12:20
【问题描述】:
使用 Crypto++ 编译时出现奇怪的转换错误
(Crypto++ 源代码直接由我的应用程序#include'd,在同一个程序集中。
所有 Crypto++ *.cpp 源文件都添加到 CMake 并直接编译。这通常可以正常工作。)
/*******************************************
** Snippet of unedited Crypto++ source code:
** misc.h
*******************************************/
template <class T>
inline void SecureWipeArray(T *buf, size_t n)
{
if (sizeof(T) % 8 == 0 && GetAlignmentOf<T>() % GetAlignmentOf<word64>() == 0)
SecureWipeBuffer(reinterpret_cast<word64 *>(static_cast<void *>(buf)), n * (sizeof(T)/8)); //error
else if (sizeof(T) % 4 == 0 && GetAlignmentOf<T>() % GetAlignmentOf<word32>() == 0)
SecureWipeBuffer(reinterpret_cast<word32 *>(static_cast<void *>(buf)), n * (sizeof(T)/4)); //error
else if (sizeof(T) % 2 == 0 && GetAlignmentOf<T>() % GetAlignmentOf<word16>() == 0)
SecureWipeBuffer(reinterpret_cast<word16 *>(static_cast<void *>(buf)), n * (sizeof(T)/2)); //error
else
SecureWipeBuffer(reinterpret_cast<byte *>(static_cast<void *>(buf)), n * sizeof(T)); //error
}
所有四行都给出相同的错误:
'static_cast':无法从 'T *' 转换为 'void *'
'CryptoPP::SecureWipeBuffer': 找不到匹配的重载函数
我正在使用 C++20 进行编译,但是在编译 C++20 之前的代码时,这应该不会导致重大问题,对吧?
我编写了一个“SecArray”类,它继承 std::array 并在对象被销毁时使用 SecureWipeArray。
(旁注:析构函数应该是虚拟的吗?std::array 没有析构函数)
namespace myNamespace
{
template<class T, size_t length>
class array : public std::array<T, length>
{
private:
using base = std::array<T, length>;
public:
inline ~array() noexcept
{
SecureWipeArray(base::data(), length);
}
constexpr inline operator T* () noexcept { return base::data(); }
constexpr inline operator T const* () const noexcept { return base::data(); }
};
}
这是我的代码唯一一次直接调用SecureWipeArray。
(我还写了一些使用std容器和CryptoPP::AllocatorWithCleanup的容器类,这反过来又调用了SecureWipeArray)
但是T应该还是基本类型,比如char、uint、string等
所以我不确定是什么导致了这个错误。
我应该从哪里寻找潜在原因?
【问题讨论】:
-
错误信息应该继续,并说明模板扩展中
T是什么类型? -
@RichardCritten 显然,即使使用 Ninja 编译 CMake 项目,Microsoft Visual Studio 也没有在错误中提供该级别的详细信息?我应该启用“详细”选项以获得更多错误详细信息吗?
-
@rustyx 不,这是一个单独的错误。
SecureWipeBuffer是一个被调用的函数,如果不先解决void*问题,编译器将无法理解该函数。 -
@n.'pronouns'm。哦,天才。这是因为我在某处声明了
array<const char>或其他东西。所以我应该使用conditional_t<is_const_v<...>...>来检查常量类型为T,并根据需要使用const_cast。让我试试这个,看看会发生什么。感谢您的提示! -
您查看的是错误视图还是编译器输出视图?编译器输出应该显示比这更多的细节。
标签: c++ casting void-pointers crypto++ reinterpret-cast