Defining arrays is one of the most basic programming language functions frequently used for software development. The following example shows a simplified code that saves a session ID using arrays.
# Define SESSION_ID_LEN_MIN 1
# Define SESSION_ID_LEN_MAX 256
Char g_SessionId [SESSION_ID_LEN_MAX];
Int save_session_id (char * _ session_id, int _ length)
{
If (_ length <SESSION_ID_LEN_MIN |
_ Length> SESSION_ID_LEN_MAX ){
Return ERROR;
}
Memcpy (g_SessionId, _ session_id, _ length );
G_SessionId [_ length] = '\ 0 ';
Return SUCCESS;
}
If you observe carefully, you will find a bug in the above sample code. This bug occurs when the value of _ length is exactly SESSION_ID_LEN_MAX, that is, 246, the array write is out of bounds. To fix this bug, the following methods may be used. The starting point of the change is to let the program return an error when the size of _ length is SESSION_ID_LEN_MAX.
# Define SESSION_ID_LEN_MIN 1
# Define SESSION_ID_LEN_MAX 256
Char g_SessionId [SESSION_ID_LEN_MAX];
Int save_session_id (char * _ session_id, int _ length)
{
If (_ length <SESSION_ID_LEN_MIN |
_ Length> = SESSION_ID_LEN_MAX ){
Return ERROR;
}
Memcpy (g_SessionId, _ session_id, _ length );
G_SessionId [_ length] = '\ 0 ';
Return SUCCESS;
}
This Code does not have any functional problems, but there is a maintainability problem. This problem is caused by the changed "> =.
Aside from the programming language syntax, if the maximum value of a mathematical variable is Y, is Y a valid value of this variable? The author understands that this value should be a valid value of the variable. Now let's look back at the previous changes, where the maximum value is treated as an invalid value, which clearly violates the general understanding of the maximum value.
Why should we point out the "small" maximum value? To understand a good programming habit, we should try to make the semantics of the program written as far as possible not contrary to the reader's common sense. For the code changed above, when the reader of the program reads "> =", it is likely to stop and think, "Why cannot it be equal to the maximum value ?". As you can imagine, the reader needs to check the size of the g_SessionId array. Then, "Oh, this is because the size of the array is SESSION_ID_LEN_MAX, however, the array definition also includes the terminator '\ 0' in the string, so the size of _ length cannot be equal to SESSION_ID_LEN_MAX. Otherwise, there is no place for the last Terminator ".
A fundamental problem with the previous program is that the common public language and programming language are combined, which makes the compiled program hard to understand, this may cause maintenance problems. Think about it. Should SESSION_ID_LEN_MAX include the last Terminator? I don't think it should be included. The final Terminator exists at the C language level. So how to make further changes to the program to improve readable maintenance? The following is a recommended method.
# Define SESSION_ID_LEN_MIN 1
# Define SESSION_ID_LEN_MAX 255
Char g_SessionId [SESSION_ID_LEN_MAX + 1];
Int save_session_id (char * _ session_id, int _ length)
{
If (_ length <SESSION_ID_LEN_MIN |
_ Length> SESSION_ID_LEN_MAX ){
Return ERROR;
}
Memcpy (g_SessionId, _ session_id, _ length );
G_SessionId [_ length] = '\ 0 ';
Return SUCCESS;
}
This change is very simple, that is, when defining the g_SessionId array, add "+ 1" after its size ", it is used to digest the character string in C language and should end with '\ 0. In addition, subtract SESSION_ID_LEN_MAX to indicate that the end character in the string is not included. The advantages of this method are:
1) it does not violate the understanding of the maximum value in public languages, that is, the maximum value is a valid value.
2) You can use consistent semantics to write programs. Subsequent Maintenance personnel can easily understand the program, making it difficult to make mistakes.
This programming habit has inspired us that programmers should try their best to think from a point of view that they do not understand the features of programming languages. This approach requires programmers not to combine different languages into languages and common public languages, resulting in readable maintenance.
This article from "to Jane Li cloud" blog, please be sure to keep this source http://yunli.blog.51cto.com/831344/228239