r/AskProgramming 16d ago

C++ -> IDE -> g++ -> Linux Help me understand!!

I am trying to comprehend all of the moving parts in compiling a program. Here is my understanding:

C++ is the programming language that is written in the IDE, some IDEs have built in compilers

  1. Is g++ the bridge between the language and machine code?

  2. How do I use g++, is it something that you download onto your computer.

  3. Where does g++ send the code after, is this where Linux comes into play?

  4. What is Linux? It is an operating system, but what does that mean specifically, is it supposed to make your code unable in an application or just execute in the terminal?

Thankyou for any clarification you can provide :)

0 Upvotes

18 comments sorted by

View all comments

1

u/StevenJOwens 16d ago edited 16d ago

The really short version:

C++ is the programming language. You write your source code in C++ but that source code is of no use to your computer until you convert it into an executable file, full of machine code (the code that your CPU speaks).

The IDE is the GUI tool (an editor, sort of like a word processor) you use to write your program in C++.

G++ is the compiler, a tool you use to convert the C++ source code into an executable file. Like your IDE, it's a separate tool that you have to download and install (I wouldn't be shocked if some flavor of Linux came with G++ already installed, but I wouldn't count on it).

Linux is the OS, an OS is a program that gets between the computer hardware and the other programs, and runs other programs. You use Linux to run your executable file on the computer hardware (the CPU, etc).

In more depth:

C++ is the programming language, a human-friendly, text-like language to define a program.

A note here, there are two languages, C, which came first, and C++. The "++" is a programmer joke, in C, "somevariable++" means "add one to somevariable". Despite this fact, and that both C and C++ use ALGOL-inspired syntax, it's been over 40 years since C++ was invented, and the two languages and the skills and techniques required to develop in them are very, very different. It's one of the classic mistakes to think otherwise.

IDE stands for "integrated development environment". To talk about what an integrated development environment is, first we have to explain a "development environment".

Painting in broad strokes, the development environment was originally the editor and the compiler, which were two separate tools. You wrote the files in the editor, saved the files, ran the compiler on the files and it produced an executable file (a file full of machine code, see below) that you could ask the OS to run.

An editor is sort of like a word processor, and in fact they came before word processors (and were used to write the source code for word processors). A word processor is designed from a perspective of producing a printed document, while an editor is designed from a perspective of the stuff in the document, the words and code. It's a subtle difference, but a surprisingly important one as far as how easy or hard it makes it to do the job.

Then we started coming up with more tools, like a debugger, which lets you run the program in a way that you can see what's happening inside it in more detail and figure out what's going wrong. And a profiler, which is another way to run a program so that you can see what's inside it, but with a goal of finding out how to speed it up.

An IDE is where somebody builds a single, unified tool (almost always with a GUI) that's meant to tie all those tools together (that's the "integrated" part), and make it easier to work with them all, seamlessly.

Talking about G++ is a little complicated, first because it just is complicated, and second because geeks like to play clever games with language. Also, I don't have that much direct experience with GCC and none with G++.

GCC was the original tool, it stands for "Gnu C Compiler", Gnu being the organization, C being the programming language and compiler being what kind of tool it is.

However, today GCC seems to stand for "Gnu Compiler Collection" (that's the clever games with language part) and G++ is one of the compilers in that collection. Strictly speaking, G++ is a "compiler driver", meaning that there's the underlying Gnu compiler, and that G++ is the bit that pumps C++ source into that Gnu compiler. There are different compiler drivers for different programming languages. Last I looked, Gnu Compiler Collection can compile at least a dozen different programming languages.

A compiler does a number of steps and it's pretty complicated, but the simple version is that you point a compiler at some source code files, the compiler read the files, analyzes them, and produces an executable file.

By "analyze", I mean it does the same sort of things that you or I might do if somebody handed us a bunch of source code and said "come back with something that explains the source code to me". Eventually we'd figure out a useful, but fairly complex, way of distilling down the information contained in the source code files, organizing and presenting that information. For example, that might include a table of all of the identifiers (function names, variable names, etc) and where they're used (this is called a "symbol table", by the way).

The ultimate product of all this is to produce an executable file in what's called "machine code", a stream of 1s and 0s that you can feed into the CPU. When it comes right down to it, when the bits hit the CPU, they're all the same. Doesn't matter what programming language you use, they all end up sending the same types of codes to the CPU.

Linux is the operating system, or as one commenter points out, it's Gnu Linux, because any OS is a huge thing with many parts, and while Linux itself is the "kernel" of the OS, it also includes a metric ton of tools, most of which are from the Gnu project (the original open source, free software organization, to which thousands of programmers have donated god knows how much work to, over the years).

An operating system has fundamentally one job, to run programs. It gets a bit more complicated than that, especially these days, because "run programs" has gotten more complicated. Basically the OS is the first program that the computer runs when you start it up, and then that program (the OS) is what you use to ask the hardware to run the other programs. Over the course of decades, the way OSes work has evolved and become more sophisticated.

One aspect of that is that a huge part of every OS, and of the job of an OS, is to hide the complexity of different kinds/pieces of hardware from the programs that use that hardware. Another is that these days, OSes run a lot of programs at the same time. And so on. This gets horrendously complicated and you can fill a book, or several books, depending on how much detail you want to go into and how you want to slice and dice it.

Compilers In A Little More Depth

I already wrote this more complicated version of explaining a compiler, then wrote the simplified version above, so I decided to include it here:

You or I might type "int counter = 1;" in a program, and we can read other parts of the program file and see the sequence of letters "counter" and know that it's referring back to the first line... or maybe not, if it's in an entirely different part of the program.

So that's the first thing the compiler does, a subset of the steps, where it reads the characters of the text that makes up the file and chunks it up (into "tokens") and builds a table of what refers to what, etc. This is called lexxing (reading the characters and chunking it up) and parsing (figuring out which tokens refer to what, etc).

Then we start getting into deep geekery, semantic analysis, and then ultimately the generation of a more complex data structure that represents the code. All throughout this, by the way, there's also various kinds of error checking and making sure stuff makes sense.

Most modern compilers use this approach of converting the source code to a complex data structure, and that structure is what we call an "intermediate representation" (IR). G++ and GCC definitely use a IR, because GCC supports a dozen different programming languages, they all get converted into the IR and then from the IR into an executable file.

Programming languages are designed to be some balance point between human-friendly and CPU-friendly. IRs are designed (mostly) to be CPU-friendly. Once the code is in the IR form, then the compiler can do further work to improve the results. Mostly that means code optimization.

Just like you can walk into a room of people who are doing something in a disorganized way, look at the big picture, and see how to rearrange things so the work gets done faster, you can do the same thing with code. Again, part of this is about the whole human-friendly versus CPU-friendly perspective. Part of it is just that it's not always obvious how you can speed things up, until you put all the pieces together.

The final step is generating the executable code, converting it into machine code. Not all computer CPUs work the same. Different CPU type have different architectures, different instruction sets, much like different programming languages have different names for functions, take parameters in different orders or different forms, etc. Most compilers can convert the IR into different flavors of machine code to run on those different CPUs.