This article is taken from the third phase of "Dr.Dobb's software research and development", "The New C: Everything is from Fortran", and the article mainly introduces the new characteristics of the C99. At the response to the author Randy Meyers and "Dr.Dobb's Software R & D" magazine, Mr. Liu Jiang's response, the previous part of the full text is published as a document, hoping to help everyone.
New C language: Everything is from Fortran
Translation: This article is a second article of one topic series of the author Randy Meyers in Cuj Magazine, mainly to tell the new keyword RESTRICT in C99 and the historical origin and way of use of Restricted Pointers. The restricted pointer is a compiler to optimize the code, which provides a specific implementation by the compiler manufacturer, so this article is not supported in all implementations, as for how to use the Restrict keyword, this article It has been a good description, and it is expected that this article can help the C language and users who use C language. In the translation, all translators have doubtful terms in the translation process or everything in the form of parentheses, sincerely do not want to mislead readers, but if you still need readers, you can use everything in this article Amstrongest@hotmail.com Contacts and discusses the translator.
Sometimes the best way to improve a language is that it is more similar to the ancient looks thirty ago.
Everything is derived from Fortran (IT All Began With Fortran).
Talking about it, I don't want to say that Fortran is the first programming language, but in the 1960s (1960s) on how to implement parameters in Fortran, it is unexpected to make Fortran The performance of the supercomputer of the 1970s (1970s) has great improvements, and resulting in a ninety-year (1990s) a new feature of the C language is accepted by C99, which is a restriction pointer. The best way to understand the original motivation of the restricted pointer is to review the history, the revision caused by the debate in Fortran.
And C is not the same, in Fortran, if a function is assigned a new value as a parameter, the real gate value passed to the function will change, and when the function returns, the caller will get a new parameter value. Consider the code exemplarities exemplaced below, if you call f as a parameter as a parameter, the Y value will be 6 when f returns. [Translation: The following programs do not have the variable y, meaning Y is the real parameter, and the X of the following program appears is a shape parameter, but it belongs to the internal variable of the function F, but after the Y is copied to X, and change x simultaneously Will change the value of the Y's Y is the value of the other.
EXAMPLE 1:
SUBROUTINE F (X)
Integer X
X = 6
End
Such parameters are transferred to the debate. Different Fortran compilers can select one of two implementations to obtain parameter password semantics in the FORTRAN. The first way is to reference the parameter transmission (by reference), that is, the typical C programmer: written a function and modify the variable in its caller. (Write a Function That Modifies a Variable In Its Caller). Passing to a function is an address of a parameter and can access this parameter indirectly anywhere when needed. If the Fortran compiler generates C code, it will be similar to the C code below the following Example 2.. EXAMPLE 2:
Void f (int * x)
{
* x = 6;
}
However, for some types of computers, indirect access to local variables is much larger than the runtime expenditure of direct reference access. This also leads to the second implementation of the parameter transmission in the FORTRAN. The address of the arguments is still passed to the function, but once the function is called, a partial copy of a real parameter will be generated [translation: transfer is the address, but the internal copy of the function is parameter value], in the function survival The local variable of this copy has been used. When the function returns, the copy variable is assigned to the parameter variable of the call function. Such a FORTRAN compiler will be similar to the following Example 3 if the C code will be generated. The input / copy output parameter delivery mode increases the burden on the function into and returns, but if a parameter is quoted multiple times, and indirect references (cost is very expensive on some machines) but no longer use The resulting result is the promotion of performance (in some machines above). [Translation: That is to say, the main call overhead of the first way is indirectly referenced. The main call overhead of the second method is a copy variable, which is better, and it is necessary to measure decision according to the real code.
EXAMPLE 3:
Void f (int * x)
{
INT Xcopy = * x;
Xcopy = 6;
* x = xcopy;
}
Most of the time, how to implement language features is usually considered to be "implementation details". They do not affect the way the programmer write a program, and the language standard committee allows the realizes of the language to freely select and change implementations. However, the Fortran program produces different results according to the parameter transfer mechanism used. Consider the Fortran code in Example 4 below, and C code converted into two ways:
EXAMPLE 4:
Subroutine G (X, Y)
Integer X, Y
X = 1 x
Y = 5 y
End
// translation using "by reference"
Void g (int * x, int * y)
{
* x = 1 * x;
* Y = 5 * Y;
}
// translation using
// "Copy In / Copy Out"
Void g (int * x, int * y)
{
INT Xcopy = * x;
INT YCOPY = * Y;
Xcopy = 1 Xcopy;
Ycopy = 5 YCopy;
* x = xcopy;
* y = ycopy;
}
G function adds different constants to the parameters, if you pass parameters A and B to function g, and the value of 1 before calling is 10. Without doubt, whether using the function parameter transfer mechanism in the Fortran, the value of A will become 2 when the function returns to the value of 2 and the value of B will become 15. But please consider, if you pass the parameters, what will be the situation? If it is a parameter transfer mechanism that uses a reference call (by reference), the value of A will become 7 when the function returns. The value of A is updated during the process of assigning * x, because X and Y are pointed to A, so the value of A in the process of assigning the value of * Y will be rewritten again. Conversely, if it is a parameter transfer mechanism using an input / copy out, a value of A will be 6 when the function returns. After the call occurs, different copy variables will be assigned to a when the function G is returned, but the return value of the last copy variable will become the final value of A. These two different parameter transfer mechanisms are representatives of any programming language definition must face. Does language require special implementation technology? Maybe this will be at the price of pay efficiency? Does the language characteristics should change in order to avoid disputes? Fortran definitions allow both parameter transfer mechanisms due to efficiency. Once such a decision makes it, some type of program will change, and will result in an Outlawed of the unclear.
The Fortran 66 standard contains a range of rules that may mislead programmers. In the list of function parameters, you can only pass once for any variable. If you pass a variable as a function parameters, then this function can no longer refer to this variable in the globics. If you pass to a variable to the function, you can't pass anything, and this function can no longer reference anything, That Overlaps it in Storage (Fortran Equivalence). Under such rules, there is no program to determine what parameter transfer mechanism should be used.
After about decade [Translation: It refers to 1970s], in order to achieve high performance of supercomputer CRAY 1, the supercomputer requires high-optimized compiler to enable traditional programs to use the machine's vector register (Vector registers). Consider the procedure in Example 5. The most efficient code for functions is to load the array pointer X, Y into the vector register and then execute the vector add-in command to add the variables in the two vector registers. If the compiler replaces the traditional usage loop to the manner to generate the vector instruction to access each element in the array, the operational efficiency of the code will be greatly improved.
EXAMPLE 5:
Void
Vector_add (float * x, float * y,
Float * result)
{
INT I;
For (i = 0; i <64; i)
Result [i] = x [i] y [i];
}