Harmful spells in programming
- Transfer
Since I watched the legendary video of Wat Gary Bernhardt, I am fascinated by the strange behavior of some programming languages. Some of them are more surprises than others. For example, for Java a whole book is written describing borderline situations and strange specificity. For C ++, you can just read the specifications for as little as $ 200.
Next, I’ll share with you my collection of the most unexpected, funny and yet valid programming spells. In fact, the use of these features of PL behavior is considered harmful, since your code should in no way be unpredictable. It is good that many linter are already aware and ready to laugh at you if you try any of the listed tomfoolery. But as they say, knowledge is power, so let's start.
It rhymes with true , so you know that it is poo ("turd").
Fortunately, this code displays
Semantics
JVM uses the same type reference for values in a range
So far, nothing too surprising.
It seems that the lower limit for the Python interpreter is the same ...
Apparently, the use of destructive assignment immediately changes the rules. I'm not sure why this is happening, and even asked a question on Stack Overflow in an attempt to figure it out. Maybe duplicate values in the list point to the same object to save memory.
The reverse record with the index instantly gives a headache to any developer.
The reason for the operation of such code is that it
At first glance, the operator
“Operator”
Operator
The operator is
Since the operator objects are
The forums / r / programminghumor full of memes of " indices , which begins with the unit ." Amazingly, many programming languages actually use 1-indexed arrays. See the full list here .
0 matched
... and only in Ruby. *
* edit: In the discussion of Reddit I was told that this is also true for Lua, Lisp and Erlang.
For historical reasons, there are alternative spellings in C for non-numeric characters.
Some alien equipment like the IBM 3270 did not allow typing some commonly used characters in C / C ++, so they introduced the use of diagrams, trigraphs, and tokens to maintain compatibility with certain encodings.
I hope the article was interesting. You can read the discussion on Reddit .
Next, I’ll share with you my collection of the most unexpected, funny and yet valid programming spells. In fact, the use of these features of PL behavior is considered harmful, since your code should in no way be unpredictable. It is good that many linter are already aware and ready to laugh at you if you try any of the listed tomfoolery. But as they say, knowledge is power, so let's start.
Enemy Reassignment True in Python 2
It rhymes with true , so you know that it is poo ("turd").
>>> True = False>>> TrueFalse
Fortunately, this code displays
SyntaxError
in the version of Python 3, since True, False and None have now become reserved words . Such a prank is still far from being mean in C ++ when you insert #define true false
a colleague into the standard header file on the working machine.Ghostly interaction with an object in Java and Python
Semantics
==
often puzzles novice Java programmers, but even more complicates the situation with operator inconsistency even in trivial situations, even if this is done for performance.Integer a = 100;
Integer b = 100;
System.out.print(a == b); // prints true
Integer c = 200;
Integer d = 200;
System.out.print(c == d); // prints false
JVM uses the same type reference for values in a range
[-128, 127]
. What is even stranger is the appropriate behavior of Python.>>> x = 256>>> y = 256>>> x is y
True>>> x = 257>>> y = 257>>> x is y
False
So far, nothing too surprising.
>>> x = -5>>> y = -5>>> x is y
True>>> x = -6>>> y = -6>>> x is y
False
It seems that the lower limit for the Python interpreter is the same ...
-5
. Integers in the range [-5, 256]
get the same ID. But it still works somehow strange.>>> x = -10>>> y = -10>>> x is y
False>>> x, y = [-10, -10]
>>> x is y
True
Apparently, the use of destructive assignment immediately changes the rules. I'm not sure why this is happening, and even asked a question on Stack Overflow in an attempt to figure it out. Maybe duplicate values in the list point to the same object to save memory.
Write back with index in C
The reverse record with the index instantly gives a headache to any developer.
int x[1] = { 0xdeadbeef };
printf("%x\n", 0[x]); // prints deadbeef
The reason for the operation of such code is that it
array[index]
is actually just syntactic sugar for *(array + index)
. Thanks to the commutative property of addition, you can swap them and get the same result.Operator "transition" in C
At first glance, the operator
-->
looks like a syntax error. But when you understand that it compiles normally, you start thinking that this is an undocumented function of the language. Fortunately, this is neither.for (x = 3; x --> 0;) {
printf("%d ", x); // prints 2 1 0
}
“Operator”
-->
is actually two operators that are dealt with in this context as (x--) > 0
. It is known that such a thing causes considerable confusion when used in production - pure evil.Operator sizeof
in C
The operator is
sizeof
processed during the compilation process, which gives it interesting properties.int x = 0;
sizeof(x += 1);
if (x == 0) {
printf("wtf?"); // this will be printed
}
Since the operator objects are
sizeof
analyzed during the compilation process, the expression (x += 1)
will never be run. Also curious: studies show that it printf("wtf?")
is the most popular line of code that never enters production.The beginning of the indices with units in Lua, Smalltalk, MATLAB, etc ...
The forums / r / programminghumor full of memes of " indices , which begins with the unit ." Amazingly, many programming languages actually use 1-indexed arrays. See the full list here .
0 matched true
in ruby
... and only in Ruby. *
if0then print 'thanks, ruby'end# prints thanks, ruby
* edit: In the discussion of Reddit I was told that this is also true for Lua, Lisp and Erlang.
Trigraphs, digraphs and tokens in C
For historical reasons, there are alternative spellings in C for non-numeric characters.
Trigraph | Symbol | Digraph | Symbol | Token | Symbol | ||
---|---|---|---|---|---|---|---|
??= | # | <: | [ | %:%: | ## | ||
??/ | \ | :> | ] | compl | ~ | ||
??' | ^ | <% | { | not | ! | ||
??( | [ | %> | } | bitand | & | ||
??) | ] | %: | # | bitor | | | ||
??! | | | and | && | ||||
??< | { | or | || | ||||
??> | } | xor | ^ | ||||
??- | ~ | and_eq | &= | ||||
or_eq | |= | ||||||
xor_eq | ^= | ||||||
not_eq | != |
if (trueandtrue) { // same as if (true && true)printf("thanks, c");
}
Some alien equipment like the IBM 3270 did not allow typing some commonly used characters in C / C ++, so they introduced the use of diagrams, trigraphs, and tokens to maintain compatibility with certain encodings.
I hope the article was interesting. You can read the discussion on Reddit .