📜 ⬆️ ⬇️

Harmful spells in programming

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 still valid programming spells. In essence, using 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 a poo ("turd").

>>> True = False >>> True False 

Fortunately, this code prints SyntaxError in Python version 3, since True, False and None are now reserved words . Such a prank is still far from being mean in C ++ when you insert #define true false into the standard header file on a co-worker’s machine.
')

Ghostly interaction with an object in Java and Python


The == semantics often perplex beginner Java programmers, but even more complicates the situation by the inconstancy of the operator, even in trivial situations, even if it is 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 

The JVM uses the same reference for values ​​in the 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 looks like the lower limit for the Python interpreter is the same ... -5 . Integers in the range [-5, 256] get the same ID. But still it 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 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" --> - these are actually two operators, which are understood 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 sizeof operator is 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 objects of the sizeof operator are analyzed during the compilation process, the expression (x += 1) will never be run. Also curious: studies show that printf("wtf?") Is the most popular line of code that never goes into production.

The beginning of the indices with units in Lua, Smalltalk, MATLAB, etc ...


The forums / r / programminghumor is full of memes about " indexes that start with one ." Amazingly, many programming languages ​​actually use 1-indexed arrays. For a more complete list, see here .

0 is true in Ruby


... and only in Ruby. *

 if 0 then print 'thanks, ruby' end # prints thanks, ruby 

* edit: In the Reddit discussion, 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 (true and true) { // 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 .

Source: https://habr.com/ru/post/345690/


All Articles