Causes and effects
Here I want to share with you three examples of inadequate code. And at the same time I will try to parse and classify each case. Thus I will tell you not only “what is bad?”, But also “why?”
Not so long ago, it was necessary to revive the once very popular project in its circles, which occupied the first lines in search engines and left a noticeable mark in the archive . Now he is quietly rolling "on neutral." After global processing and launching the project in full force, I will write “how it was”. And now about the code that did not pass censorship.
A similar code has already been published on Habrahabr . Short. By reference: select the identifier for inserting a new element into the MySQL database table (select the largest identifier, add one, insert a new record). The author of the masterpiece that I want to present to you has gone even further. The ID is randomly selected, attempts to insert a record do not stop until the pseudo-random number generator guesses the free ID.
The code looked something like this:
Cause. The author’s ignorance of SQL features (auto_increment in particular).
Tip. Study, study and study again. Read smart books, watch other people's codes, criticize your own code, seek advice from more experienced programmers.
In the tenth grade at an informatics lesson, I was given the task of writing a program that determines whether the entered number is a full square. The program was written and set off. Two years later, having run my eyes over the code, I could not understand why it works. The algorithm consisted in comparing the root of the entered number and the private number entered and its root (see code below).
It looked like this:
Cause. I have not analyzed my code. From a mathematical point of view, the condition "sqrt (x) = x / sqrt (x)" is always satisfied (for x> 0), and only due to the limitation of the bit network of operands did the program fulfill its function (an error occurred at the end of the fractional part).
Tip. Understand your code. Make sure that the program runs the planned processes.
And finally, a terrible bedtime story. The following code, unlike the above, has never been written by anyone (I really hope so). Although its counterparts in other programming languages seem to be found in reality. For example, #define TRUE FALSE (C, I suppose?), Mentioned earlier . Or the notorious “dog” (@) in PHP.
Assembler:
I will not assure you that this code is workable (I have dealt with assembler for a long time ... and not true). The general meaning that I wanted to convey: the address of the stack segment is placed on the stack, a random value is written to the address register of the stack segment, then some actions and the “recovery” of the register of the address of the stack segment from the “stack”. What will happen next is unknown to anyone. Such cases threaten a very long debugging.
Cause. Absolutely not thought out the sequence of operations. The consequences to which a harmless set of teams may lead are not taken into account.
Tip. To control the indirect influence of the written code on what was written earlier or may be written in the future. Avoid implicit restrictions imposed by the code on the program as a whole and its individual sections.
Everything written above can be found in any literate programming book. And, perhaps, now, you will want to read one of them. Also, I hope, now, you will become more attentive to your code.
upd : Due to the emergence of a large number of defenders of "random" identifiers in the database tables, I will answer everyone right away: if you need to hide real IDs, you need to use mod_rewrite and not distort the database.
Lack of knowledge / experience.
Not so long ago, it was necessary to revive the once very popular project in its circles, which occupied the first lines in search engines and left a noticeable mark in the archive . Now he is quietly rolling "on neutral." After global processing and launching the project in full force, I will write “how it was”. And now about the code that did not pass censorship.
A similar code has already been published on Habrahabr . Short. By reference: select the identifier for inserting a new element into the MySQL database table (select the largest identifier, add one, insert a new record). The author of the masterpiece that I want to present to you has gone even further. The ID is randomly selected, attempts to insert a record do not stop until the pseudo-random number generator guesses the free ID.
The code looked something like this:
$id = 0;
while (!$id || mysql_error()) {
$id = rand(1, 10000000);
mysql_query("INSERT INTO `table` (id) VALUES ('".$id."'");
}
Cause. The author’s ignorance of SQL features (auto_increment in particular).
Tip. Study, study and study again. Read smart books, watch other people's codes, criticize your own code, seek advice from more experienced programmers.
Misunderstanding.
In the tenth grade at an informatics lesson, I was given the task of writing a program that determines whether the entered number is a full square. The program was written and set off. Two years later, having run my eyes over the code, I could not understand why it works. The algorithm consisted in comparing the root of the entered number and the private number entered and its root (see code below).
It looked like this:
readln(x);
if sqrt(x) = x/sqrt(x) then
writeln(x, ' - полный квадрат')
else
writeln(x, ' - не является полным квадратом');
Cause. I have not analyzed my code. From a mathematical point of view, the condition "sqrt (x) = x / sqrt (x)" is always satisfied (for x> 0), and only due to the limitation of the bit network of operands did the program fulfill its function (an error occurred at the end of the fractional part).
Tip. Understand your code. Make sure that the program runs the planned processes.
Inattention.
And finally, a terrible bedtime story. The following code, unlike the above, has never been written by anyone (I really hope so). Although its counterparts in other programming languages seem to be found in reality. For example, #define TRUE FALSE (C, I suppose?), Mentioned earlier . Or the notorious “dog” (@) in PHP.
Assembler:
push ss
mov ss, 01f7
; ...
pop ss
I will not assure you that this code is workable (I have dealt with assembler for a long time ... and not true). The general meaning that I wanted to convey: the address of the stack segment is placed on the stack, a random value is written to the address register of the stack segment, then some actions and the “recovery” of the register of the address of the stack segment from the “stack”. What will happen next is unknown to anyone. Such cases threaten a very long debugging.
Cause. Absolutely not thought out the sequence of operations. The consequences to which a harmless set of teams may lead are not taken into account.
Tip. To control the indirect influence of the written code on what was written earlier or may be written in the future. Avoid implicit restrictions imposed by the code on the program as a whole and its individual sections.
Everything written above can be found in any literate programming book. And, perhaps, now, you will want to read one of them. Also, I hope, now, you will become more attentive to your code.
upd : Due to the emergence of a large number of defenders of "random" identifiers in the database tables, I will answer everyone right away: if you need to hide real IDs, you need to use mod_rewrite and not distort the database.