There is definitely not an equivalence between delete int_ptr; and delete char_ptr;, based on assembly compiled from some basic C++ code:
//C++ Code
void delete_as_int(int* ptr) {
delete ptr;
}
void delete_as_char(char* ptr) {
delete ptr;
}
//Assembly; GCC 8.2 x86-64, no optimizations, c++17 mode
delete_as_int(int*):
push rbp
mov rbp, rsp
sub rsp, 16
mov QWORD PTR [rbp-8], rdi
mov rax, QWORD PTR [rbp-8]
mov esi, 4 //Difference!
mov rdi, rax
call operator delete(void*, unsigned long)
nop
leave
ret
delete_as_char(char*):
push rbp
mov rbp, rsp
sub rsp, 16
mov QWORD PTR [rbp-8], rdi
mov rax, QWORD PTR [rbp-8]
mov esi, 1 //Difference!
mov rdi, rax
call operator delete(void*, unsigned long)
nop
leave
ret
Simply put, the assembly to delete an int* calculates a different number of bytes to store in a register than the assembly to delete a char* does.
So just on the face of things, it's clear that the type the compiler recognizes matters. Even if for no other reason than to ensure that the correct amount of memory is deleted. So you can't rely on the compiler to magically deduce the correct behavior for deleteing a pointer that has had its type altered by the reinterpret_cast call: you need to make sure to delete pointers as the type they were created as—or for polymorphic types, ensure that the Deleter is virtual.