For example, the variable gap is defined as char in nqpd.c, but referenced in nqp3.c as short: nqp3.c:6:21: warning: type of ‘gap’ does not match original declaration [-Wlto-type-mismatch] 6 | chsdim, chpdim, gap; | ^ nqd.c:24:72: note: type ‘char’ should match type ‘short int’ 24 | outf1[80], outf2[80], outfd[80], outcopy[80], act, ch1, crel, cfm, gap; | ^ nqd.c:24:72: note: ‘gap’ was previously declared here Redefining exp (of <math.h> fame) as a variable could cause problems as well: pcp.c:10:31: warning: built-in function ‘exp’ declared as non-function [-Wbuiltin-declaration-mismatch] 10 | short npt, np, npt1, nb, exp, prime; | ^~~ Defining functions as returning short and calling them through an implicit function declaration (which has an implied return type of int) is undefined, too: pcscfns.c:21:11: warning: type of ‘image’ does not match original declaration [-Wlto-type-mismatch] 21 | addsv(image(p[base[i]]), svptr[i]); | ^ permfns.c:53:7: note: return value type mismatch 53 | short image(short pt) | ^ permfns.c:53:7: note: type ‘short int’ should match type ‘int’ permfns.c:53:7: note: ‘image’ was previously declared here These are just examples. I suggest to collect all extern declarations in the "defs.h" header, and then make sure that the types match. Reproducible: Always