Lecture
The g ++ compiler is distributed under the GNU license, the Free Software Foundation (FSF), for nix-like operating systems and is a C ++ compiler that is managed using the command line. g ++ is distributed with nix systems, so if you are running Unix or Linux, most likely g ++ is already installed on your system.
To run the source code using the g ++ compiler, simply type the following com in the terminal (command line) ***:
After the source file is compiled into an executable file, we will get a file with the name a
and the extension .out
- a.out
.
Before running g ++, you can specify the name of the executable file on the command line, which we get at the output. To do this, specify the -o
parameter and assign the desired file name.
Completely com *** and will look like this:
In order for g ++ to show error warnings and also support existing C ++ standards, I recommend using the flags:
If you want the compiler to treat warnings as errors, use the -Werror
flag. And if at least one warning appears, you will not even get the executable file. This way you will know for sure that you have not missed a single error.
If you want to debug the executable file in the GDB debugger, include the -g
flag in the *** command.
This will allow the GDB debugger to give you detailed information about the debugging process, including additional code in the executable file.
If you are using * nix-like systems, you can also check other g ++ compiler options by typing the following com *** u in the command line:
or
If you want to learn how to create a shared library on Linux with gcc, read the article How to create a shared library on Linux using gcc.
The gcc compiler is distributed under the GNU license, the Free Software Foundation, for nix-like operating systems, and is a C \ C ++ compiler that is managed using the command line. gcc is distributed with nix systems, so if you are running Unix or Linux, most likely gcc is already installed on your system.
To run the source code using the gcc compiler, just type the following com in the terminal (command line) *** y:
After the source file is compiled into the executable, we will get a file with the name a
and the extension *.out
- a.out
, which can be run using the command
Before running gcc, you can specify the name of the executable file on the command line, which we will get on output. To do this, set the -o
parameter and assign the desired file name.
Completely com *** and will look like this:
Again, you can start the program with the command ./outputfile
. (The dot and slash ./
in front of the file name are used to indicate the current directory.)
To display all warnings, you must use the flag:
To be sure that the compiler really supports ANSI standards, use the flag:
You can read more about the meaning of compiler warnings.
If you want the compiler to treat warnings as errors, use the -Werror
flag. In this case, if at least one warning occurs, you will not receive an executable file.
If you want to debug the executable file in the GDB debugger, include the -g
flag in the *** command.
This will allow the GDB debugger to give you detailed information about the debugging process, including additional code in the executable file.
If you need to use functions from the math library (as a rule, functions from the math.h
header file, such as sin
or sqrt
), you must explicitly specify this file. To bind the library, the -l
flag is used, followed by the m
library flag:
Note that in C ++ you do not need to use this flag.
If you are using * nix-like systems, you can also check other gcc compiler options by typing the following com *** u in the command line:
manual (in English) to the gcc compiler, or
manual (in Russian) to the gcc compiler.
If you want to learn how to create a shared library on Linux with gcc, read the article: How to create a shared library on Linux using gcc.
This is your first C (or C ++) program — it’s not that big, and you’re going to compile it. You click on the compile
(or enter a com *** at the compilation) and wait. Your compiler produces fifty lines of text. You choose the words warning
and error
. You wonder if this means that everything is in order. You are looking for the resulting executable file. Nothing. Damn it, you think, I have to figure out what it all means ...
First, let's distinguish between types of errors. Most compilers will display three types of warnings at compile time:
Although you don’t want to ignore them, the compiler warnings are not serious enough to not compile your program. Read the following article, which will tell you why you should be friends with the compiler and its warnings. As a rule, compiler warnings are a sign that something can go wrong during execution. How does the compiler know about it? You must have made typical mistakes that the compiler knows about. A typical example is the use of the assignment operator =
instead of the equality operator ==
inside an expression. Your compiler may also warn you about using variables that have not been initialized and other similar errors. As a rule, you can set the level of warnings of your compiler - I set it to the highest level, so the compiler warnings do not turn into errors in the program being executed (“run errors”).
However, compiler warnings should not stop your program (unless you tell the compiler to treat warnings as errors), so they are probably not as serious as errors.
Compiler errors are limited to individual source code files and are the result of “syntax errors”. Actually, it means that you did something that the compiler cannot understand. For example, the expression for(;)
syntactically incorrect, because the loop must always have three parts. Although the compiler was expecting a semicolon, it could also expect a conditional expression, so the error message you get may be something like:
Note that compiler errors will always include the line number on which the error was found.
Even if you have completed the compilation process successfully, you may encounter linker errors. Linker errors, unlike compiler errors, have nothing to do with the wrong syntax. Instead, linker errors are usually problems finding the definition of functions, structures, classes, or global variables that were declared, but not defined, in the source code file. As a rule, these errors will look like:
Typically, the compilation process begins with a series of compilation errors and warnings and, correcting them, you will encounter linker errors. In turn, I would first fix compilation errors, and then linker errors.
If you are faced with a list of fifty or sixty errors and warnings, it will be difficult to determine where to start. The best place, however, is at the top of the list. In fact, you almost never start correcting errors from the end of the file to its beginning for one simple reason: you don’t know if they really are errors!
One error at the top of your program can cause a number of other compiler errors, because these lines can count on something at the beginning of the program that the compiler could not understand. For example, if you declare a variable with an incorrect syntax, the compiler will report syntax errors and that it cannot find the declaration for the variable. Semicolons, put in the wrong place, can lead to a huge number of errors. This happens because the C and C ++ syntax allows you to declare a type immediately after its definition:
1
2
3
4
5
|
struct { int x; int y; } myStruct; |
the code will create a variable, MyStruct
, with space to hold the structure containing two integers. Unfortunately, this means that if you omit the semicolon, the compiler will interpret it as if the next thing in the program is a structure (or returns a structure).
Something like that:
1
2
3
4
5
6
7
8
|
struct MyStructType { int x; int y; } int foo() {} |
can lead to a huge number of errors, possibly including messages:
All this because of one character! Best to start from the top.
Most messages from the compiler will consist of at least four things:
The output of g ++ for the above program may look like this (your results may differ if you use another compiler):
foo.cc is the file name. 7 - line number, and it is clear that this is a mistake. The short message here is very useful, because it shows exactly what is wrong. Note, however, that the message makes sense only in the context of the program. It does not indicate which structure is missing a comma.
More confusing is another error message from the same compilation attempt:
The programmer must figure out why this happened. Note again that this error was caused by a problem at the beginning of the program, not on line 8, but earlier, when the structure lacks a semicolon. Fortunately, it is clear that the definition of the function for foo was fine, it tells us that the error should be somewhere else in the program. In fact, it should be in the program before - you will not receive an error message that indicates a syntax error before the line on which the error actually occurred.
It will be much worse if the compiler does not tell you what happened earlier in the program. Even the first compiler error you get may be related to several lines before the specified warning.
There are several particularly complex types of compiler errors. The first is an undeclared variable that you think you declared. Often, you can specify exactly where the variable was declared! The problem is that often the variable is simply written with an error. Unfortunately, it is rather difficult to see, since we usually read what we expect, and not what we really are. In addition, there are other reasons why this may be a problem - for example, problems with visibility!
To sort out possible problems, I do this: in the line where the allegedly undeclared variable is located, you need to perform a search using the text editor for the word under the cursor (alternatively, you can copy the variable name and perform the search), and if I recorded it incorrectly, it will not be found . Also, do not enter the variable name manually, as you may accidentally enter it correctly.
The second incomprehensible message:
What's happening? Why is the end of the file "unexpected"? Well, the main thing here is to think like a compiler; if the end of the file is unexpected, then it must be waiting for something. What could it be? The answer is usually "completion". For example, closing curly brackets or closing quotes. A good text editor that performs syntax highlighting and automatic indentation should help correct some of these errors, making it easier to detect problems when writing code.
Ultimately, if the message is incomprehensible, then approach the problem, thinking about how the compiler is trying to interpret the file. It can be difficult when you are just starting out, but if you pay attention to the messages and try to understand what they might mean, you will quickly get used to the general patterns.
Finally, if nothing works, you can always just rewrite a few lines of code to remove any hidden syntax errors that you might not see. This can be dangerous, since you can rewrite the wrong section, but it can help.
After you have finally fixed all the syntax errors, took a nap, a snack a couple of times and prepared yourself mentally for the correct compilation of the program, you can still encounter linker errors. They are often quite difficult to fix, because they are not necessarily the result of what is written in your program. I will briefly describe the typical types of linker errors that can be expected, and some ways to solve them.
You may have problems with how you set up your compiler. For example, even if you include the right header files for all of your functions, you still need to provide your linker with the correct path to the library that has the actual implementation. Otherwise, you will receive an error message:
Pay attention to the support of these functions by the compiler (this can happen if you include your own function declaration to bypass the error during compilation). If your compiler supports this feature, then problem resolution usually requires specific compiler settings. You should tell the compiler where to look for the libraries and make sure the libraries have been installed correctly.
Linker errors can occur in functions that you declared and defined if you did not include all the necessary object files in the binding process. For example, if you write a class definition in myClass.cpp
, and your main function is in myMain.cpp
, the compiler will create two object files, myClass.o and myMain.o, and the linker will need both of them to complete the creation of the new program. If you leave myClass.o
, then it will not have a class definition, even if you correctly include myClass.h
!
Sometimes minor errors occur when the linker reports more than one definition for a class, function, or variable. This problem may appear for several reasons: first, an object may have two definitions — for example, two global variables are declared as external variables, to be accessible outside the source code file. This applies to both functions and variables, and this, in fact, often happens. On the other hand, sometimes this is a problem with linker directives; Several times I have seen people include multiple copies of the same object file in the binding process. And bingo, you have several definitions. A typical manifestation of this problem is that a number of functions have several definitions.
Last weird type of linker error - message
This linker error differs from others in that it may have nothing to do with the object, including files or the correct paths to your library. On the contrary, this means that the linker tried to create an executable file and could not understand where the main()
function is located. This can happen if you forget to include the main function, or if you try to compile code that has never been a separate executable file (for example, if you tried to compile a library).
Comments
To leave a comment
LINUX operating system
Terms: LINUX operating system