Final dream of programming language: static type safety

zhaozj2021-02-16  55

Always listen to people say "strong type". But individuals have different understandings about strong types.

Some think that C is a strong type, and some believe that C is also a strong type. Because they all have type checks.

It can be seen that if there is no clear definition, talk about "strong type" is inevitably inevitable.

So what kind of definition can you give "Strong Type"?

The most original definition is this: The static type system will check all errors. As long as the static type is checked, the program will not have bugs.

However, it is obvious that this is unrealistic because some bugs are purely logical. For example:

Print "Hell World"

It is ranging from an O. It is bug, but the computer does not force this unless it is added, the computer is in power.

So, we define strong types as:

The static type system checks all types of errors, as long as the type check is passed, it is guaranteed that there will be no apple as a gasoline.

As for the type matching error, we define it:

When you try to handle a variable as a type A, it is unexpected that it is not type A. It may be type B, or it is nothing.

Cautiously, we can exclude the situation of using Downcast. If you don't have to

(Gasoline) New Apple (), you can find it, we can't manage it.

This can be said to be the highest realm pursued by all support types. Think about it, once your program is compiled, no matter how millions of rows, you can confidently: I have only logical errors in my program.

How good! ! !

So, what language has reached this request? C? C ? Java?

Unfortunately, they are not.

Let's talk about C,

Union is familiar? You mix two different types to a memory space. Then use a variable to identify its true type.

However, if your program is incorrectly turned into type B, the compiler will not warn you.

Also, char * p = "Hello World";

This sentence is not type safe. If you do P [0] = 'x'; the compiler will not be wrong, because the type of P is char *, and the subscript operation of char * is completely legal.

There is still a lot of other uncommon places.

C ? The problem mentioned above is equally there.

There are some less obvious types of vulnerabilities.

1. Placement New. Look at this code:

X * px = new x ();

NEW (PX) y ();

PX-> m ();

Here, the compiler does not report an error, but the result of PX-> M () is unknown.

Some people explain: This is because the objects pointing to PX have no longer exist. However, we don't study why it fails, you can have a thousand reasons to explain why your program crashes, but the fact is very simple: it crashed. Because you want to use a Dongdong that is not X as X.

2. Delete P;

Very surprised?

X * px = new x ();

Delete PX;

PX-> m ();

A simple manner is bypass the compiler and get a type matching error. You can also hang the pointer error, but according to our definition of the error, we want to treat the PX as x *, but in fact it is not what we expect, so it is also a type of incorrect. Otherwise, it is not fair to other types of vulnerabilities.

Your px-> m () does not have to be an example in the PX-> m () security of the one. Why is I am a type error, are you not? Look at Java, Java has a great progress in Type security compared to C / C . The problem mentioned above, there is no existence in Java. Java threw away UNITION, throws away the pointer, and the design of these designs can be discussed in efficiency. However, an obvious fact is that its type system is safer.

Java adopts garbage collection mechanism. This is controversial for many C / C programmers who are accustomed to managing memory. However, if the efficiency is not considered, only from the type of security perspective, it eliminates the type security vulnerability brought by Delete, and the statically type security in the real sense is close.

However, Java is not a full static type of security.

Lack of flood-shaped support, but programmers should frequently do similar (Apple) OBJ; this Downcast is greatly increased. Fortunately, in Java, I also realized this, all kinds of efforts are trying to add generics to Java. However, this is not the purpose of this article to be discussed, and after all, our premise is not considered DOWNCAST.

So, don't you use Downcast, is the Java program is still safe?

Please see this code:

String [] sa = new string [100];

SA [0] = "Hello World";

Object [] OA = SA;

OA [0] = new integer (1);

System.out.println (SA [0]);

through! The gunpowder bucket exploded!

The reason is that Object [] OA = sa; this sentence.

According to the principle of the Candarity in the type theory, only read only object [] can be the parent type of String []. However, there is no reading in Java to read such a type, and the tragedy happened like this.

The same hidden dangers are also present in some dimensional languages. If the language wants to provide the support, if you want myTemplate is the parent type of MyTemplate , then the reference to the Object type is not casual in the definition of MyTemplate. It must conform to the rules of the cohance, only in the coordinated position.

There is also a place where a static type system is inseparable, such as:

String s [] = new string [2];

s [2] = "Hello World";

boom! The tragedy happened again. .

It meets the definition of our pairing error: You try to handle S [2] as a string, but actually it is not.

This problem exists in almost various languages ​​that support arrays.

Because the length of the array can be arbitrary, it is difficult to design a type system to static guarantee that the boundary of the array will not be crossed.

Pascal tries to do this, which helps the static type system work by adding the length of the array on the type.

However, a quantity array can guarantee type security, because the array of different sizes cannot be converted, the flexibility of the program is greatly sacrificed.

Java's solution is very realistic: since this is not good, then it is. I joined the boundary check at runtime, although it is not possible to securely guarantee the boundary security of the array, at least the big leak can not be made. In fact, in theory, Java's practice is to convert an undefined type matching error to a relatively safe definition object state error by changing the dynamic semantics of the array.

Yeah, how is a perfect thing? After all, the program will always have illegal state as a state machine. In fact, there is still another solution.

ML, the old seniors in this programming language. Almost a Type of Functional Language.

What is its plan?

Simple, you can't be simple, that is: I don't want arrays!

It sounds scary, however, this is consistent with the policy of Functional Language, because the array is a data structure that requires side effects, and Functional is to abandon side effects, so Functional discarding array is also natural. (Ironically, some of the extensions of ML also add array, because arrays are the necessary paths that implement the data structure such as Hash Table.)

Sarrely, basically reverse the possible type system vulnerabilities from the ditch, sun drying the sun.

C # how? I am just a glimpse of C #, when I saw it, I forgot it for a long time. However, this array of offshore issues, I believe it still exists.

If we reality, throw away the problem of the array of crosses this unlikely, then, the only thing that makes me worry about C #, that is, the array of cohabese problems.

Which C # high people are interested in confidence?

转载请注明原文地址:https://www.9cbs.com/read-26036.html

New Post(0)
CopyRight © 2020 All Rights Reserved
Processed: 0.044, SQL: 9