Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Understanding C++ compilers from a Java / C# perspective

I'm a moderately experienced Java / C# programmer, and I've recently started learning C++. The problem is, I'm having trouble understanding how to structure the various header and code files. This seems mostly due to my lack of understanding as to how the compiler links everything together. I've tried reading some textbooks, but my preconceptions are heavily colored by my Java and C# knowledge. For example, I'm having a hard time coming to grips with the fact that methods and the like can be defined in a namespace rather than only in a class definition.

I've found plenty of C++ -> Java/C# guides, but practically nothing to go the other way. Are there any good resources out there for easing the Java/C# -> C++ transition, particularly with respect to understanding the compiling process?

like image 652
Whatsit Avatar asked Feb 10 '09 16:02

Whatsit


People also ask

What is the difference between C compiler and Java compiler?

Java is a high-level language because translation of code takes place into machine language using compiler or interpreter. C is a compiled language that is it converts the code into machine language so that it could be understood by the machine or system.

How does C compiler work?

The compiler checks the source code for the syntactical or structural errors, and if the source code is error-free, then it generates the object code. The c compilation process converts the source code taken as input into the object code or machine code.

Can we write C code in Java?

It's not possible to run C source code at all unless you can find a C interpreter.

How is C compiler compiled?

Usually, a first compiler is written in another language (directly in PDP11 assembler in this case, or in C for most of the "modern" languages). Then, this first compiler is used to program a compiler written in the language itself. You can read this page about the history of the C language.


1 Answers

The C++ FAQ is an excellent resource about all the idiosyncrasies of C++, but it's probably a little more advanced than you're looking for -- most of the questions (not just the answers) are mysteries even to fairly experienced C++ developers.

I think if you google for C++ tutorials, you'll be able to find something. You may also want to try learning assembly language (or at least getting a quick introduction as to how things actually happen in a microprocessor), as both C and C++ are quite close to the hardware in the way they do things. This is where their speed and power comes from, but it comes at the price of some of the nicer abstractions Java offers.

I can try to answer your specific questions asked above, but I don't know how well I'll do.

One of the keys to understanding the relationship between header files and cpp files is understanding the idea of a "translation unit". A Java class file can be considered a translation unit as it is the basic unit that is compiled into a binary form. In C++, pretty much every cpp file is a translation unit (there are exceptions if you're doing weird stuff).

A header file may be included in multiple translation units (and must be included everywhere that uses whatever is defined in the header). The #include directive literally just does a text substitution -- the contents of the included file are inserted verbatim where the #include directive is. You normally want your class interface to be defined in the header file, and the implementation in the cpp file. This is because you don't want to be exposing your implementation details to other translation units that may include the header. In C++, everything, including classes, aren't really rich objects, but just chunks of memory that the compiler assigns meaning to... by compiling the same header information into each translation unit, the compiler guarantees that all the translation units have the same understanding of what a chunk of memory represents. Because of the lack of rich data after compile time, things like reflection are impossible.

The second step in the C++ build process is linking, which is where the linker takes all the compiled translation units and looks for symbols (usually function calls, but also variables) used in a translation unit but not defined there. It then looks for another translation unit that defines that symbol and "links" them together, so that all calls to a particular function are directed to the translation unit that defines it.

In the case of class methods, they must be called through a class instance, which is behind the scenes just a pointer to a piece of memory. When the compiler sees these types of method calls, it outputs code that calls a function, implicitly passing the pointer, known as the this pointer, to the function as the first argument. You can have functions that do not belong to classes (not methods, as you said, because a method is properly a member function of a class and thus cannot exist without a class) because the linker has no concept of a class. It will see a translation unit that defines a function and another that calls a function and tie them together.

That ended up being a lot longer than I expected, and of course is an oversimplification, but it is accurate to the best of my knowledge and the level of detail provided... hope it helps some. At least it should give you a starting point for some googling.

like image 158
rmeador Avatar answered Oct 18 '22 14:10

rmeador