This behavior is actually specified by POSIX standard, which all Bourne-like shells should support to claim themselves portable.
sh -c [-abCefhimnuvx] [-o option]... [+abCefhimnuvx] [+o option]...
command_string [command_name [argument...]]
command_string parameter ? Now let's look at
-c flag description:
Read commands from the command_string operand. Set the value of special parameter 0 (see Special Parameters) from the value of the command_name operand and the positional parameters ($1, $2, and so on) in sequence from the remaining argument operands. No commands shall be read from the standard input.
In other words, where in normal shell script
$0 (which is usually shell name in interactive mode or script name when you run a script) would be set by the shell itself, with
-c you have to specify it yourself. Thus,
sh -c 'echo Hi, I am $0 , my first positional parameter is $1' foobar 5
would set the process name to
Just in case you're wondering what
$0 is, it's also covered in "Special Parameters" section of Shell Command Language Specifications:
(Zero.) Expands to the name of the shell or shell script.