gzip 1.6 or above, FreeBSD and derivatives or recent versions of NetBSD, see don_cristi's answer.
With any version, you can use shell redirections as in:
gzip < file.txt > file.txt.gz
When not given any argument,
gzip reads its standard input, compresses it and writes the compressed version to its standard output. As a bonus, when using shell redirections, you don't have to worry about files called
"-" (that latter one still being a problem for
gzip -c --).
Another benefit over
gzip -c file.txt > file.txt.gz is that if
file.txt can't be opened, the command will fail without creating an empty
file.txt.gz (or overwriting an existing
file.txt.gz) and without running
gzip at all.
A significant difference compared to
gzip -k though is that there will be no attempt at copying the
file.txt's metadata (ownership, permissions, modification time, name of uncompressed file) to
file.txt.gz already existed, it will silently override it unless you have turned the
noclobber option on in your shell (with
set -o noclobber for instance in POSIX shells).