C, 64 60 bytes
main(s){printf(s="main(s){printf(s=%c%s%1$c,34,s);}",34,s);}
This may segfault on 64-bit systems with some compilers, such as newest Clang, due to the type of s being interpreted as 32-bit int instead of a pointer.
So far, this is the shortest known C quine. There's an extended bounty if you find a shorter one.
This works in GCC, Clang, and TCC in a POSIX environment. It invokes an excessive amount of undefined behavior with all of them.
Just for fun, here's a repo that contains all the C quines I know of. Feel free to fork/PR if you find or write a different one that adds something new and creative over the existing ones.
Note that it only works in an ASCII environment. This works for EBCDIC, but still requires POSIX. Good luck finding a POSIX/EBCDIC environment anyway :P
How it works:
main(s)abusesmain's arguments, declaring a virtually untyped variables. (Note thatsis not actually untyped, but since listed compilers auto-cast it as necessary, it might as well be*.)printf(s="..."setssto the provided string and passes the first argument toprintf.sis set tomain(s){printf(s=%c%s%1$c,34,s);}.- The
%cis set to ASCII34,". This makes the quine possible. Nowslooks like this:
main(s){printf(s="%s%1$c,34,s);}. - The
%sis set tositself, which is possible due to #2. Nowslooks like this:
main(s){printf(s="main(s){printf(s=%c%s%1$c,34,s);}%1$c,34,s);}. - The
%1$cis set to ASCII 34",printf's first** argument. Nowslooks like this:
main(s){printf(s="main(s){printf(s=%c%s%1$c,34,s);}",34,s);}
... which just so happens to be the original source code.
* Example thanks to @Pavel
** first argument after the format specifier - in this case, s. It's impossible to reference the format specifier.
I think it's impossible that this will get any shorter with the same approach. If printf's format specifier was accessible via $, this would work for 52 bytes:
main(){printf("main(){printf(%c%0$s%1$c,34);}",34);}
Also here's a longer 64-byte version that will work on all combinations of compilers and ASCII environments that support the POSIX printf $ extension:
*s;main(){printf(s="*s;main(){printf(s=%c%s%1$c,34,s);}",34,s);}