C language compiler issues

Source: Internet
Author: User

Basic explanation

    • This section describes a series of common programming problems caused by the following two features of the C compiler.
    • Compile C files separately:
      CProgramIt is usually composed of several small programs (. c files). The Compiler compiles these small programs separately and then combines them together to form a goal.Code. Since the compiler can only compile one file at a time, it cannot immediately check for errors that can be found only when several source files are used together.
    • Create temporary variables for function parameters and return values
      The C compiler creates a temporary parameter for the function parameter, and may implicitly pass a pointer to the function return value. Because of the implicit nature of these temporary variables, a series of problems may occur in some cases, especially when pointers exist.
    • The header file contained in the C file will be compiled together with the C Language

      The header file contained in the C language is compiled with the. c file. Problems in the header file are reflected in the compilation of the. c file.

Problem: separate compilation of C files

I have an array a defined in f1.c, but I want to calculate the number of its elements in f2.c. Can sizeof be used for this purpose?

Answer and analysis:

The answer is no. you have no way to achieve your goal. The essential reason is that the sizeof operator only works in "compile time", and the unit of C language compilation is each time. compile the c file (also in other languages ). Therefore, sizeof can determine the size of an array in the same source file, but it is powerless to define an array in another source file, because it is already "Run Time).

There will always be a way to do one thing. There are three options below to solve this problem:

1) define a global variable to remember the size of the array. in the c file, we can access this global variable to obtain the array size information (it seems that the problem is not worth the candle ).

2) In. in the H file, the macro is used to define the size of the array, for example, # define array_size 50, which is included in both source files. h file. You can directly access array_size to obtain different definitions. the size of the array in the C file.

3) set the last element of the array to a special value, such as 0,-1, null, etc. Then we traverse the array to find this special ending element, to determine the length of the array (this method is inefficient and stupid ).

Problem: Implicit pointer passing in function return values

The following code works normally, but a fatal error occurs at the end of the program. Why?

Struct list
{
Char * item;
Struct list * next;
}

Main (argc, argv)
{
...
}

Answer and analysis:

The reason is very simple. Note that adding a semicolon after the right-side arc of the definition structure list can solve this problem:

Struct list
{
Char * item;
Struct list * next;
}; // This Semicolon is missing!

Okay, the problem is solved. But do you know what the fatal problem is caused by this error? The problem is not that simple on the surface. OK. Let's take a look at the truth behind the incident.

First, take a look at the following code:

Void func (struct my_struct STX)
{
.......
}
Struct my_struct sty = {...};
Func (STY );

When the function func is called, the value of the Structure Variable sty is copied to the call stack and passed to the function func as a parameter. This is called the parameter value of C language. I believe you know this clearly, so you should know: If the return value of a function is a structure variable, how should the function return the value to the caller? See the following code:

Struct my_structfunc (void)
{
.......
}
Struct my_struct sty = func ();

In this case, the return value of the function func is a value of the structure type, which is put in a dark and horrible place in the memory, at the same time, a pointer is arranged to point to this place (temporarily called "mysterious Pointer"), which will be passed to the function func as a hidden parameter by the C language compiler. When the function func returns, the code generated by the compiler copies the value in the memory zone pointed to by the hidden pointer to the returned structure stash, so as to return the structure variable value to the caller.

Now that you understand the things mentioned above, the real cause of today's problem is coming to the fore:

Because struct list {...} the main function main (argc, argv) is understood by the compiler as a function whose return value is a structure variable, in this way, we expect to get the third parameter except argc and argv, that is, the implicit "mysterious Pointer" we mentioned above ". However, as you know, the function here is the main function, and the parameters of the main function are provided by the startup code in the program. While the startup code certainly thinks that the main () should be born to get only two parameters, "mysterious Pointer", of course not. In this way, main () the third parameter (the mysterious pointer) that does not exist in the stack is called independently when the returned result is returned, leading to illegal access and fatal problems. This is the real root cause of this problem.

Suggestion:

1) try to use the pointer of the Structure Variable instead of the structure itself as the function parameter. Otherwise, the overhead of memory copy during function calling is not small, especially for scenarios with frequent calls and large structs.

2) The structure definition must be followed by a plus sign. As described in the above section, I believe you will not make the same mistake.
Problem: the compiler will implicitly create a temporary copy for the parameter of the function.

What are the results of running the test function?

Void getmemory2 (char ** P, int num)
{
* P = (char *) malloc (Num );
}

Void test (void)
{
Char * STR = NULL;
Getmemory (& STR, 100 );
Strcpy (STR, "hello ");
Printf (STR );
}

Answer and analysis:

This is the example above in Lin Rui's "high quality programming guide for C/C ++.

In this way, the call will have the following two consequences:

1) Output hello

2) Memory leakage

Another related question:

What are the results of running the test function?

Void getmemory (char * P)
{
P = (char *) malloc (100 );
}

Void test (void)
{
Char * STR = NULL;
Getmemory (STR );
Strcpy (STR, "Hello World ");
Printf (STR );
}

Answer and analysis:

The execution result is a program crash. After running debugging, we can see that STR in the test function is still null after getmemory. One call can be imagined

Strcpy (STR, "Hello World ");

The program will inevitably crash.

Cause analysis:

The C compiler always creates a temporary copy for each parameter of the function. The copy of the pointer parameter P is _ p, and the compiler makes _ p = P. If the program in the function body modifies the content of _ p, the content of parameter P is modified accordingly. This is why pointers can be used as output parameters. In this example, _ P applied for a new memory, but changed the memory address indicated by _ p, but P was not changed at all. Therefore, the getmemory function cannot output anything. To output dynamic memory, use a pointer to a pointer or a pointer to a reference.

Question: The header file is compiled with the. c file containing it.

The following code is very short and looks like no problem, but the compiler will report an error. Where can this problem occur?

# Include "someheader. H"
Int Myint = 0;

Answer and analysis:

You don't have to stare at int Myint = 0; look, this assignment should be the simplest statement in C language, and the problem will certainly not be in it, so the problem may only occur in someheader. in H, the most common one is that the declaration (function or variable) of the last line of the header file does not end with a semicolon ";", then the compiler will combine it with the Myint variable for consideration, naturally, an error occurs.

This problem mainly reminds you to broaden your thinking when locating the problem. You may need to consider whether the header file contains a problem.

Conclusion: The included header file is compiled with the. c file. The problems in the header file are reflected in the. c file compilation. Remember.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.