有害なプログラミングの呪文

伝説のWat Gary Bernhardtのビデオを見て以来、プログラミング言語の奇妙な振る舞いに魅了されてきました。 それらのいくつかは他のものよりも多くの驚きを持っています。 たとえば、境界線の状況と奇妙な詳細を説明するJava向けの本全体が書かれています。 C ++の場合、わずか200ドルで仕様を読むことができます。

次に、最も予期せず面白い、まだ有効な「プログラミング」スペルのコレクションを紹介します。 実際、PLの動作のこれらの機能の使用は、コードが決して予測不可能であってはならないため、有害であると見なされます。 これらのトリックのいずれかを試してみると、多くのリンターがすでに知識があり、あなたを笑う準備ができているのは良いことです。 しかし、彼らが言うように、知識は力なので、始めましょう。

Python 2での敵の再マッピングTrue


trueで韻を踏むので、あなたはそれがうんち (「うんち」)であることを知っています。

>>> True = False >>> True False 

幸いなことに、このコードはPython 3でSyntaxErrorSyntaxErrorます。これは、 True、False、およびNoneが予約語になったためです。 この種のいたずらは、同僚の作業マシンの標準ヘッダーファイルに#define true falseを挿入したときのC ++の意地悪とはほど遠いものです。

JavaおよびPythonでのオブジェクトとのファントム相互作用


セマンティクス==初心者のJavaプログラマーを困惑させることがよくありますが、状況をさらに複雑にしているのは、たとえパフォーマンスのためにこれを行ったとしても、些細な状況であってもオペレーターの矛盾です。

 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は、範囲[-128, 127]値に同じタイプの参照を使用します。 さらに奇妙なのは、対応するPythonの動作です。

 >>> x = 256 >>> y = 256 >>> x is y True >>> x = 257 >>> y = 257 >>> x is y False 

これまでのところ、驚くべきことは何ありませ

 >>> x = -5 >>> y = -5 >>> x is y True >>> x = -6 >>> y = -6 >>> x is y False 

Pythonインタープリターの下限は同じように見えます... -5[-5, 256]範囲の整数は同じIDを取得します。 しかし、それでも何らかの形で奇妙に動作します。

 >>> x = -10 >>> y = -10 >>> x is y False >>> x, y = [-10, -10] >>> x is y True 

明らかに、破壊的な割り当てを使用すると、すぐにルールが変更されます。 私はこれがなぜ起こるのか分かりません、そしてそれを解明しようとしてStack Overflow質問さえしました。 リスト内の重複値は、メモリを節約するために同じオブジェクトを指している可能性があります。

Cのインデックスを使用したライトバック


インデックスを使用したライトバックは、開発者にとってすぐに頭痛の種になります。

 int x[1] = { 0xdeadbeef }; printf("%x\n", 0[x]); // prints deadbeef 

このコードが機能する理由は、 array[index]が実際には*(array + index)単なる構文上の糖だからです。 加算の可換特性により、それらを交換して同じ結果を得ることができます。

Cの遷移演算子


一見すると、演算子-->は構文エラーのように見えます。 しかし、正常にコンパイルされることを理解すると、これは文書化されていない言語の機能であると考えるようになります。 幸いなことに、これはどちらでもありません。

 for (x = 3; x --> 0;) { printf("%d ", x); // prints 2 1 0 } 

「演算子」 -->は実際には、このコンテキストでは(x--) > 0として(x--) > 0れる2つの演算子です。 そのようなものは、生産で使用するとかなりの混乱を引き起こすことが知られています-純粋な悪。

Cのsizeof演算子


sizeof演算子は、コンパイルプロセス中に処理され、興味深いプロパティを提供します。

 int x = 0; sizeof(x += 1); if (x == 0) { printf("wtf?"); // this will be printed } 

sizeof演算子のオブジェクトはコンパイル中に解析されるため、式(x += 1)は実行されません。 また、好奇心が強い:研究は、 printf("wtf?")が本番稼働にprintf("wtf?")最も人気のあるコード行であることを示しています。

Lua、Smalltalk、MATLABなどの単位でインデックスを開始する


/ r / programminghumorフォーラムには、「 1 始まる インデックス 」に関するミームがたくさんあります 。 驚くべきことに、多くのプログラミング言語は実際に1インデックス配列を使用しています。 完全なリストはこちらをご覧ください。

0はRubyでtrueと一致しtrue


...そしてRubyのみ。 *

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

*編集:Redditの議論で、これはLua、Lisp、Erlangにも当てはまると言われました。

Cの3文字表記、2文字表記、およびトークン


歴史的な理由により、Cは英数字以外の文字の代替スペルを残しています。

トリグラフ記号ダイグラフ記号トークン記号
??=#<:[%:%:##
??/\:>]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"); } 

IBM 3270などの一部の外部機器は、C / C ++で一般的に使用される一部の文字の入力を許可していなかったため、特定のエンコードとの互換性を維持するために、ダイアグラム、トライグラフ、およびトークンの使用を導入しました。

この記事がおもしろいことを願っています。 Redditに関する議論を読むことができます。

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


All Articles