Aqui está uma implementação.

#include<stdio.h>
#define my_sizeof(type) (char *)(&type+1)-(char*)(&type)
int main()
{
    double x;
    printf("%ld", my_sizeof(x));
    getchar();
    return 0;
}

O tipo é como uma variável local para a macro. & tipo fornece o endereço da variável (duplo x) declarado no programa e incrementando-o com 1 dá o endereço onde a próxima variável do tipo x pode ser armazenada (aqui addr_of (x) + 8, pois o tamanho de um duplo é 8B )
A diferença dá o resultado que quantas variáveis ​​do tipo x podem ser armazenadas naquela quantidade de memória que obviamente será 1 para o tipo x (para incrementar com 1 e tirar a diferença é o que fizemos). Fazer o Typecast em char * e pegar a diferença nos dirá quantas variáveis ​​do tipo char podem ser armazenadas no espaço de memória fornecido (a diferença). Uma vez que cada char requer apenas 1B de memória, portanto (quantidade de memória) / 1 dará o número de bytes entre duas localizações de memória sucessivas do tipo da variável passada para a macro e, portanto, a quantidade de memória que a variável o tipo x requer.
Mas você não conseguirá passar nenhum literal para essa macro e saber seu tamanho.

Você também pode implementar usando a função em vez de uma macro, mas a implementação da função não pode ser feita em C, pois C não suporta sobrecarga de função e sizeof() deve receber parâmetros de todos os tipos de dados.

Observe que a implementação acima assume que o tamanho do caractere é de um byte.

Complexidade de tempo: O (1)
Complexidade de espaço: O (1)

Quer aprender com os melhores vídeos com curadoria e problemas práticos, confira o C++ Foundation Course for Basic to Advanced C++ e C++ STL Course for Foundation plus STL. Para completar sua preparação desde o aprendizado de um idioma até o DS Algo e muitos mais, consulte o Curso Completo de Preparação para Entrevistas .