The keyboard sends character codes.
USB keyboards send keycode 42 for the Backspace key
and the default ukbd keymap translates this into ASCII code 0x08.
PS/2 keyboards send keycode 14 for the Backspace key
and the default pckbd keymap translates this into ASCII code 0x7f.
The tty driver interprets several characters in canon mode for editing.
With
stty erase ^H
you tell it to 'backspace' when receiving 0x08.
With
stty erase '^?'
you tell it to 'backspace' when receiving 0x7f.
This is what you see when running 'cat'.
Editors and line-editing libraries or shells run the tty driver in
raw or cbreak mode and handle editing on their own. They either
copy the behaviour of the tty driver by reading the tty driver
settings, or use some hard encoded mapping (often 0x08 and 0x7f are
then treated the same) or have a custom configuration.
That's why you can edit your shell commands despite getting a ^H
from the keyboard while the tty driver is configured for ^?.
The tty driver settings are usually set within some login script,
either by calling the stty program or by running tset. tset
gets its information from the termcap/terminfo database where
it looks up an entry for the environment variable TERM. TERM
can come from different sources, the default value for a console
login comes from /etc/ttys, remote logins usually inherit it from
the client.
Some other programs also get their information from termcap/terminfo
which has the disadvantage that every computer has its own database
which might be wrong for remote connections if both computers do not
agree. That's often true for e.g. xterm and the reason why xterm
can be configured to override the termcap/terminfo database.
Graphical programs (other than terminal emulators) usually do not
use a tty. So all the above may not have any meaning for them. X11
has an old method (xmodmap) and a new method (xinput) to handle
keyboard mappings and semantics, but that's another story.