10 июля 2012

Следи за мной, компилятор!

Привет. Вот такой небольшой хинт который работает на последних версиях GCC и Clang точно.

Хинт этот касается статических ассертов, и проверки типов, которая обычно компилятором не проводиться. Все это актуально для Cи++.

Герои дня: __is_pod.

#include <stdio.h>
#include <string.h>

#define _STATIC_ASSERT(COND,LINE) typedef char _assert_##LINE[(COND)?1:-1]
#define STATIC_ASSERT(COND) _STATIC_ASSERT(COND, __LINE__)

struct Foo
{
  int x;
  int y;
  int z;
};

class Moo
{
  public:
    Moo() : x(0), y(0), z(0) {}
    void print(){ printf("%d, %d, %d\n", x, y, z); }

  private:
    int x;
    int y;
    int z;
};

template<typename T>
void copy(T& dest, const T& src)
{
  STATIC_ASSERT(__is_pod(T));
  memcpy(&dest, &src, sizeof(T));
}

int main(int argc, char **argv)
{
  Foo foo = {0, 0, 0};
  Foo bar;
  copy(bar, foo);

  Moo mfoo;
  Moo mbar;
  copy(mbar, mfoo);
  return 0;
}

Вот так вот можно на этапе компиляции убедиться что шаблонная функция copy используется исключительно для POD типов.