Compilers and Programming errors

Compiler

Image result for compilers 

A compiler is a special program that processes statements written in a particular programming language and turns them into machine language or "code" that a computer's processor uses. Typically, a programmer writes language statements in a language such as Pascal or C one line at a time using an editor. The file that is created contains what are called the source statements. The programmer then runs the appropriate language compiler, specifying the name of the file that contains the source statements.

When executing (running), the compiler first parses (or analyzes) all of the language statements syntactically one after the other and then, in one or more successive stages or "passes", builds the output code, making sure that statements that refer to other statements are referred to correctly in the final code. Traditionally, the output of the compilation has been called object code or sometimes an object module . (Note that the term "object" here is not related to object-oriented programming.) The object code is machine code that the processor can execute one instruction at a time.

The Java programming language, a language used in object-oriented programming, introduced the possibility of compiling output (called bytecode ) that can run on any computer system platform for which a Java virtual machine or bytecode interpreter is provided to convert the bytecode into instructions that can be executed by the actual hardware processor. Using this virtual machine, the bytecode can optionally be recompiled at the execution platform by a just-in-time compiler.

Traditionally in some operating systems, an additional step was required after compilation - that of resolving the relative location of instructions and data when more than one object module was to be run at the same time and they cross-referred to each other's instruction sequences or data. This process was sometimes called linkage editing and the output known as a load module.

A compiler works with what are sometimes called 3GL and higher-level languages. An assembler works on programs written using a processor's assembler language.

 

The compiler errors and warnings

 

The compiler is the program that, given a set of code files, translates them to generate a file ready to be executed. But for this translation to be possible, the program must comply with a set of requirements imposed by the programming language. The type of checks done during this translation depends both on the programming language and the compiler itself. When a construction not allowed by the programming language is detected, the translation is stopped and a message is shown.

These messages do not explain the cause that produced them, but the low level anomaly detected by the compiler. For this reason, it is sometimes difficult to identify the true reason behind a compiler error.

1.  Errors and warnings

The C programming language is defined such that numerous decisions are taken by the compiler automatically when no information is found in the code. In other words, the compiler takes decisions about how to translate the code that the programmer has not written in the code. This, in some cases, is convenient because the programs can be written more succinctly, but only expert programmers take advantage of this feature. The recommendation is to use an option for the compiler to notify all those cases where there are implicit decisions. For the gcc compiler, this option is -Wall.

The compiler shows two types of anomalies: errors and warnings. An error is a condition that prevents the creation of a final program. No executable is obtained until all the errors have been corrected. The first errors shown are the most reliable because the translation is finished but there are some errors that may derive from previous ones. Thus, if the first errors are fixed, it is recommended to compile again and see if other later errors also disappeared.

Warnings are messages that the compiler shows about special situations in which an anomaly has been detected, but making some assumptions, the translation may proceed. Thus, a compilation does not finish until all errors are fixed, but the final executable program may be obtained with any number of warnings. When gaining experience in C programming and until a complex application is designed (multiple source code files), the recommendation is:

Compile always with the -Wall option and do not consider the program correct until all warnings have been eliminated.

2.  Most common compiler messages

It follows a description of the messages that are most commonly shown by the compiler. Sample code is shown to illustrate the cause of the error, but each program has a different structure and therefore, the error may appear due to some different high level causes.

  1. `variable' undeclared (first use in this function)

    This is one of the most common and easier to detect. The symbol shown at the beginning of the message is used but has not been declared. Only the first appearance is shown.

  2.   warning: implicit declaration of function `...'

    This warning appears when the compiler finds a function used in the code but no previous information has been given about it. The compiler assumes that the function returns an integer and proceeds.

    These warnings are those that we recommend you eliminate before trying the execution of the program. Depending on the situation, there are several ways to eliminate this message. The compiler needs to know how the found function is defined. For that, in a previous location in the code the file must included, either the entire function definition or its prototype (the data type of the result followed by the name, a parenthesis with the parameter definition and a semicolon.

    If this information (the function definition) is needed in several files, then, instead of writing the same information in all of them, it is recommended to include the function prototype in a file which is then included where needed through the use of the #include pre-processor directive. Remember that the code of a function may only appear in a single location in the code. If the compiler finds the function body in more than one location an error will be shown to flag the multiply defined function.

    It may be also the case that the required information is contained in a file to be included because the function is part of a library. To check if a function is in any of the C standard libraries we recommend the use of the man command followed by the function name. If the function is part of a library, the manual page shows the file that needs to be included in our code (if any).

  3.  warning: initialization makes integer from pointer without a cast

    This warning tells us that we have used a pointer in a context where an integer is expected. This is allowed in C and the compiler knows how to perform the translation, but it warns us just in case we want to confirm the operation using a cast. The following code shows an example that produces this warning.

    int main (void)

     {

     char c = "\n";  /* incorrect? */

     return 0; 

    }

    In the first line a pointer to a character (because an string is internally stored as a memory address, which indicates the address where the first letter of the string is located) is assigned to a character. Although c is defined as a character, the compiler treats it as an integer, and this is legal. The string "\n" is taken as a pointer and that is the reason for the warning message. A pointer is being assigned to a variable that is not a pointer, it may be considered as an integer and furthermore, a casting is not being used.

    In most of the cases, this assignment is in fact a programmer error and needs to be fixed. But it is possible that a pointer has to be manipulated as a integer as it is shown in the following program:

    int main (void) 

    {

     int value = "\n"; /* Correct Assignment */

     return 0;

     }

    Let us assume that in this case the programmer does need to store this pointer in an integer variable. The compiler still shows the warning. To confirm the compiler that this is really our intent, a casting can be used, that is, a prefix to the symbol name where the new type is written in parenthesis. Once added this prefix, the compiler understands that this assignment is truly what the programmer wants, and the warning is not shown.

    int main (void) 

     {

     int value = (int)"\n"; /* Correct assignment confirmed by the programmer    using the cast */ 

    return 0;

     }

  4. Dereferencing pointer to incomplete type

    This error appears when a pointer to a structure is used to access to one of its fields but the compiler does not have enough information about the structure. The following program shows this situation:

    struct btree * data;

     int main (void) 

     {

     data->size = 0;   /* Incomplete information */ 

    return 0;

     }

    The declaration of variable data as a pointer to a btree structure is correct. Declaring a pointer to a structure does not require the structure to be defined. But in the first line of function main this pointer is used to access one of the fields in the structure. In this case, the definition of the structure is not present and the error is shown.

    The most probable cause for this error is that the definition of the structure is in another file and must be present before using the pointer to access a field. For this reason, the structure definitions are typically written in files with extension *.h that are then included in the code files.

  5. Warning: control reaches end of non-void function

    This warning appears when a function has been defined as returning a result but no return statement has been included to return this result. Thus, either the function is incorrectly defined or the statement is missing. The compiler is still capable of generating, and even though the function does not contain the statement, a result is returned to the function that performed the invocation.

  6. Warning: unused variable `...'

    This warning is printed by the compiler when a variable is declared but not used in the code. The message disappears if the declaration is removed.

  7. Undefined reference to `...'

    This message appears when there is a function invoked in the code that has not been defined anywhere. The compiler is telling us that there is a reference to a function with no definition. Check which function is missing and make sure its definition is compiled.

  8.  Error: conflicting types for `...'

    Two definitions of a function prototype have been found. One is the prototype (the result type, name, parenthesis including the parameters, and a semicolon) and the other is the definition with the function body. The information in both places is not identical, and a conflict has been detected. The compiler shows you in which line the conflict appears and the previous definition that caused the contradiction.

3.  Execution error

 Image result for execution error

Execution error is when a programing language is running post compilation and the logic flow has any defect. This error can only be figured out when the program is running.
If the machine language cannot comprehend the logic during the execution then it will result in execution error.

The execution of C programs may terminate abruptly when an error is detected. But unlike other programming languages, when an error is detected, instead of printing a detailed report on the error, C programs only print the succinct message Segmentation fault. There is no additional information about the cause of the error, so you need to review you code and its execution to fix it.

 

 

 

Comments

Popular Posts