Включенные охранники не защищают вас от определения объекта несколько раз, если вы включаете определение в несколько единиц перевода!
В качестве решения никогда не define вещи в заголовках, но только объявляют их:
// header
extern char EL[2];
// TU
#include "header.h"
char EL[2] = "el";
// Other consumer
#include "header.h";
// can now use EL
(Конечно, есть исключения; например, определения классов хороши (но определения функций-членов класса не являются (но встроенными являются)) - будьте осторожны.)
Я должен добавить, что в качестве альтернативы вы можете сказать static
в своем заголовочном файле, чтобы сделать определение частным для каждого TU:
// header
static char EL[] = "EL"; // every TU gets a copy
(В C ++ 0x вы не можете использовать объекты статической связи в качестве параметров шаблона.)