Harmful spells in programming

Original author: Evan Rose
  • 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.

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 SyntaxErrorin 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 falsea 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 sizeofin C


The operator is sizeofprocessed 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 sizeofanalyzed 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 truein 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.

TrigraphSymbolDigraphSymbolTokenSymbol
??=#<:[%:%:##
??/\:>]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 .

Also popular now: