编译关于非普通旧数据的memset的时间警告

Hen*_*rik 8 c++ compiler-warnings

我正在开发一个大型代码库,将一些旧的C模块转换为C++.我想将一个C++对象添加到一个struct,但是这个struct的一些用户memset呢,这对于我想放在struct中的对象来说是不幸的.

如何在编译时检测到这是否正在完成,以便我可以消除memset对不再是POD的这种结构的所有使用?

Naw*_*waz 8

我不确定编译器是否会通过直接提供一些编译标志来帮助你.如果确实如此,对你有好处.用那个.故事结局.

如果没有,那么这可能会对你有所帮助.由于您将代码从C转换为C++,这意味着memset的所有用法都没有std::命名空间.所以利用这个事实,#define memset如下:

 #define memset memset_if_pod_else_error() 
Run Code Online (Sandbox Code Playgroud)

memset_if_pod_else_error是您编写的函数(即您必须实现它).您可以将其设为模板,以便推断出参数的类型,然后检测该类型是否为POD.如果它是POD,那么这很好,并在std::memset内部调用,否则引发错误.

元函数喜欢std::enable_ifstd::is_pod会帮助你实现这个功能.

这是这个想法的最小演示:

#include <iostream>
#include <type_traits>
#include <cstring>

auto ptr_memset =  std::memset; //store this a pointer

template<typename T>
using VoidPtr = typename std::enable_if<std::is_pod<T>::value, void*>::type;

#define memset memset_if_pod_else_error

template<typename T>
VoidPtr<T> memset_if_pod_else_error(T *data, int ch, size_t count) 
{
      return ptr_memset(data, ch, count);
}

struct pod {};
struct nonpod { nonpod() {} };

int main()
{
    pod p;
    nonpod np;

    memset(&p, 0, sizeof(p));

    memset(&np, 0, sizeof(np));  //this is error!
}
Run Code Online (Sandbox Code Playgroud)

第二次调用memset生成此错误:

错误:没有用于调用'memset_if_pod_else_error'mexset的匹配函数
(&np,0,sizeof(np));
^ ~~~~~

在线演示.

希望有所帮助.