My remembrance is a little vague at this time, but basically what I think is happening is this:
Say you need to #include a file something.h in your main sketch. Let's also presume you have other .cpp files as part of your project. What happens is: The Arduino IDE copies everything into a temporary directory (on Linux, it's /tmp/build############.tmp, where the "#" signs represent a long string of numbers). Your .ino file is renamed as a .cpp file, so the compiler can do its work as usual. All of your cpp files are compiled to .o files. All of the components defined in the .ccp files are created in the .o files at compile time: code is created, memory is set aside for them, values are assigned, etc. The only thing that remains is to link them all together in the final compile step.
Well: if you #include a file in a .cpp file, it is as if the file was part of the .cpp file. If you define a function in one .o file, and define it in another .o file, at the time linking takes place, how does the compiler know that those functions are one and the same? It doesn't, and it can't. Remember, the Arduino IDE does funky stuff... all the .o files are created separately from each other. So the compiler complains because it finds a function by the same name, defined twice, and it has no way to tell which one you actually want.
I wanted to solve this problem: There are a number of #defines that one can set in one's sketch to modify the behavior of the PinChangeInt library. I could force the programmer to go to another .h file and modify it, but forcing a developer to modify a .h file that was downloaded in a package is a bad practice: This means you must modify it for your particular sketch, but what happens if you come back a month or a year later and reuse the library for another project? Maybe you don't remember that you did something to the downloaded .h. The developer must be able to depend on the contents of the delivered files at all times.
So I think it is more important to allow the developer to #define what they need to in an expected place, and leave the code and its files which were delivered- that is, the library- alone. So I did the ugly thing and put everything in the .h file. Remember, it is ugly mostly to me (the developer of the library) but clean to the sketch writer. I can handle it, because I'm the guy who wrote the library and I should have a deeper understanding of it. So when a developer of a sketch #define's something to modify the library's behavior, and then #includes the library's .h file afterwards, the proper behavior is seen and it is encapsulated in the current project.
However, the problem of compiling the library's functions and variable definitions multiple times remains, if the developer uses the library in another file as part of their project. What I need to do is tell the compiler not to compile everything multiple times: Since the .ino file of the sketch #includes the library, we can rest assured that all components of the PinChangeInt library are compiled already. So I include a directive in the PinChangeInt.h: #ifndef LIBCALL_PINCHANGEINT. So #define LIBCALL_PINCHANGEINT precede #include PinChangeInt.h in every file that #includes it, *except* the original sketch.