Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I'm writing my first programming language that is object orientated and so far so good with create a single 'class'. But, let's say I want to have to classes, say ClassA and ClassB. Provided these two have nothing to do with each other then all is good. However, say ClassA creates a ClassB--this poses 2 related questions:

-How would the compiler know when compiling ClassA that ClassB even exists, and, if it does, how does it know it's properties?

My thoughts thus far had been: instead of compiling each class at a time (i.e scan, parse and generate code) each "file (not really file, per se, but a "class") do I need to scan + parse each first, then generate code for all?

share|improve this question

3 Answers 3

up vote 12 down vote accepted

Different languages (and thus compilers) approach this differently.

In the C family, the different modules have a corresponding header file that is used while building the object. The header files provide information on the size of the object and what functions or methods exists that may be invoked. This allows for the necessary information for memory allocation and "does that method/function/procedure exist?" that is used when doing compilation of a single unit that doesn't need to have access to the source itself.

In Java, the compiler is aware of things on its classpath and inspects those object to link against them (verifying that methods exists, have the right number of arguments, etc...). Java may also link dynamically at runtime loading in other classes that it doesn't know anything about when it was compiled. See Class.forName for one example of dynamic loading.

Both options are quite valid and have their own set of advantages and disadvantages. Providing header files some see as cumbersome and violating DRY. On the other hand, if you don't have header files libraries need to be inspectable by the compiler and linker - a .so or .dll likely won't have enough information in it to properly instantiate the objects or validate the method calls (and would be machine dependent).

share|improve this answer

Older languages sometimes are more strict; consider what is possible in Java:

public interface Ifc {
    public static final Ifc MY_CONSTANT = new Implem();
}

public class Implem implements Ifc {
}

I have seen the anti-pattern above, and it is really ugly (I would have forbidden it). Both compilation units use each other. But Ifc can be compiled to code without having a compiled Implem. The compiled code, .class, comparable to a C .obj, contains "linkage information:" an import of Implem, calling a parameterless constructor Implem(). The Implem class can then compiled without problem. Partly the ClassLoader - doing initialisation/build JVM class data, and partly the Java Virtual Machine itself, play a bit as linker, integrating all.

For instance compiling with one version of a specific library, and running with another version of that library will recognize runtime errors.

So the answer: Compilation delivers units of compiled object code, which one has to see as code + data + API for linking together.

The compiler should afterwards also do a packing together, and verify the linkage API; a second phase.

This might irritate and look inelegant, but mathematical proofs may operate in the same way: in proving the entire correctness one may already consider a part to hold true till verification.

share|improve this answer

Practically speaking, with Java, the IDE's look at a whole program at once; when ClassB is referenced, the IDE compiler will look at it. Everything, including the libraries, is one complete whole. Once the program is ready, you can change classpaths, swap in and out individual .class files, and switch library versions. You could also compile individual .java files without using the IDE (or somehow avoiding it's checks). The result does not need to be consistent at all, and if it's not you will get run-time exceptions. (One of the many things an IDE is trying to do for you is turn run-time errors into compile-time, or rather, edit-time, errors.)

C#'s about the same, and I don't think C and C++ are really that different, in that what the Java and C# IDE's are doing is just creating C/C++-style headers for you behind the scenes.

share|improve this answer
    
Java compilers compile dependent stuff as well, if necessary. You only get runtime exceptions from this sort of thing if you've really tried very hard to force things (e.g., changing and recompiling an API after compiling the consumers of that API). –  Donal Fellows Jun 28 '12 at 14:33
    
@DonalFellows: My problems have been missing libraries ("But I put that one on all my machines!") and recompiling running programs (unintentionally hot-swapping .class files). I can foresee updating packages that no longer match the main program, though I haven't done it yet. I did do a lot of that with C and .dll's (and had it done to me) years ago. I believe and hope there are a lot of protections in place now that weren't there then. –  RalphChapin Jun 28 '12 at 14:45
    
I really don't get what an IDE has to do with how a compiler/linker knows how to solve compile/linker problems. Correct me if I'm wrong, but an IDE is totally orthogonal to the whole issue (except that it eases the task on the programmer). Why? Because in theory the IDE uses the compiler in the background. –  Thomas Eding Mar 24 at 19:43
    
@ThomasEding: You're quite right. When I answered this question I seemed to be having trouble separating the IDE from the compiler/linker. My excuse: Java does not "link" until it runs and so cannot know a class ref or method call is wrong until then; the IDE does not really "ease" my task, it makes it possible. I used (in FORTRAN and C, long long ago) to get errors when I compiled, when I linked, and then when I ran. Now I get almost all those errors right as I type them in, which makes the IDE a compiler, linker, and executer, in a sense. Today, all non-run-time errors come from the IDE. –  RalphChapin Mar 25 at 20:06

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.