It's common in C (and other languages) to use prefixes and suffixes for names of variables and functions. Particularly, one occasionally sees the use of underscores, before or after a "proper" identifier, e.g. _x and _y variables, or _print etc. But then, there's also the common wisdom of avoiding names starting with underscore, so as to not clash with the C standard library implementation.
So, where and where is it ok to use underscores?
Good-enough rule of thumb
That's it. You might still have a conflict with some file-specific definitions (see below), but those will just get you an error message which you can take care of.
Safe, slightly restrictive, rule of thumb
These rules forbid a bit more than what is actually reserved, but are relatively easy to remember.
More detailed rules
This is based on the C2x standard draft (and thus covers previous standards' reservations) and the glibc documentation.
Don't use:
__(two underscores)._D)._.atomic_,memory_,memory_order_,cnd_,mtx_,thrd_,tss_LC_,SIG_,ATOMIC,TIME__t(that's a POSIX restriction; for C proper, you can use this suffix unless your identifier begins withintoruint)Additional restrictions are per-library-header-file rather than universal (some of these are POSIX restrictions):
dirent.hd_fcntl.hl_,F_,O_, andS_grp.hgr_limits.h_MAX(also probably_MIN)pwd.hpw_signal.hsa_andSA_sys/stat.hst_andS_sys/times.htms_termios.hc_And there are additional restrictions not involving underscores of course.