Error codes are among the worst inventions, and cause no end of problems during refactoring. What should you function return if underlying function fails with FILE_NOT_FOUND error?
Should you just pass it through or maybe you should just invent your own exit codes? What about additional information (you know, a user might want to know the name of the file that has not been found)? Should we store it in a thread-local variable? Hm. Who is going to release it when it's not needed?
And what about compounded errors, i.e. we want to know how NAIL_NOT_FOUND caused THE_KINGDOM_WAS_LOST error? We might want a stacktrace!
And when you solve all these problems you'll get exceptions. Except they probably will be badly implemented.