[... not what one could naïvely expect...]
The two code snippets are not equivalent.
Consider what happens with all the combinations of Inf, 0 and NaN: the simple routine will return some surprising results, all the pirouetting in the
complex.h version is needed to keep them straight.
The way they should work is described for C11 in Annex G IEC 60559-compatible complex arithmetic.
Note that the annex is normative (if __STDC_IEC_559_COMPLEX__ is defined - which gcc does not by default, AFAICS), so a compliant implementation needs to abide by it.
So, even without
declaring full compliance, they are trying to make things right.
Use -ffast-math (or -ffinite-math-only) to get
the same (unsafe, but mostly OK if one accepts the non compliance) results.
Yes, definitely complex stuff...