Damit du den #if/#else-Haufen nicht brauchst, gibt's doch
extra _AVR_LIBC_VERSION_. Deren Wert wächst monoton mit
den Versionen, du kannst ihn also mit einem einfachen >
vergleichen.
Außerdem haben wir <avr/version.h> noch von <avr/io.h> mit
includiert, damit es in einem Headerfile auftaucht, was es
garantiert schon früher gab und was sowieso praktisch jeder
bereits benutzt. Für eine avr-libc-Version < 1.4.x kannst
du also mit
#if _AVR_LIBC_VERSION_ < 10400UL
testen. (Unbekannte Makros ersetzt der Präprozessor in
mathematischen Ausdrücken durch den Wert 0. Das ist vom
Standard abgedeckt.)
GCC belegt den Makro _GNUC_ mit seiner major version, also
#if _GNUC_ >= 4 gilt für alles ab GCC 4.x. Außerdem gibt's
noch _GNUC_MINOR_.
Du solltest natürlich einen sinnvollen Test vornehmen, also
_AVR_LIBC_VERSION_ wenn es um Features der avr-libc geht,
_GNUC_, wenn es um den Compiler selbst geht.