Yes, it's unintuitive behavior. You should avoid comparing signed and unsigned integers in the first place! I wish GCC would give a warning, but it actually only seems to give a warning on your first example...
Here's the thing. When you compare values that are smaller in size than int, the compiler does integer promotion, making those values both ints, regardless of signed vs unsigned. This is what's happening in your second example; both are being promoted to ints in the comparison. And 255 != -1.
In your first example, since unsigned long is >= int, integer promotion does not happen, but the normal rules of unsigned and signed behavior happens: When comparing signed with unsigned, the compiler converts the signed value to unsigned, so -1 becomes ULONG_MAX.
This seems like a good blog post that explains the behavior you're seeing:
https://blog.regehr.org/archives/268
Also, why hardcode the numbers in the print statement's numbers? Different compilers will have different max numbers, hence the use of things like ULONG_MAX.
Edit:
Also, your title is wrong. No integer overflow is happening. Integer overflow is a specific thing that causes undefined behavior.