役に立たないように見えるプログラム内の行を書く[終了]


26

プログラムを作成し(サイズは重要ではありません)、役に立たない行を追加しますが、実際にはそうではありません-削除すると、プログラムがクラッシュするか、何か間違ったことをします。コメントで未使用に見える行を自由にマークするか、以下の例のようにコードの説明に言及してください(もちろん、この例では、行は実際には必要ありません。これは単なる例です)。

int main(void) {
    /* The line below is actually needed. */
    2 + 2;

    return 0;
}

これは人気コンテストなので、投票数が最も多いソリューションが勝ちます。


2
例の行が必要なのはなぜですか?
ガリBN

3
@GariBNそうではありません。「この例では、行は実際には必要ありません。単なる例です。」
エリキシニド14年

9
グッド@EdCottrellは...私はいくつかの基本的な事を逃したと思った...知っている
ガリBN

2
それ必要です。例のために。:-)
フロリアンF 14年

1
このサイトでは、人手不足の課題がトピックではなくなったため、この質問をトピック外として終了することに投票しています。meta.codegolf.stackexchange.com/a/8326/20469
cat

回答:


33

C

int main(int argc, char **argv) {
    switch(argc) {
        case 2:
            ;
            int allowed = 0;
        case 3:
            argc--;
            break;
        default:
            argc = 3;
    }
    return 0;
}

シングルを削除すると、コンパイルされません;

編集

以下のソリューション:

これは、caseステートメントが単なるラベルであり、そのためにステートメントが続く必要があるために発生します(標準では、宣言を除外する「実行されるアクションの指定子」と呼ばれます)。これを防ぐために、我々は、との宣言の前に付け;NULL文。仕様caseのラベルを見つけることができ、ここでページ142(ドキュメント内131)で


4
GCCは「ラベルはステートメントの一部にしかなれず、宣言はステートメントではない」と言っています。
ボルティコ14年

1
私は学校で書いているプログラムでこれに噛まれました。
ケビン-復帰モニカ14年

これにより、実際のプログラムは実際には非常に見苦しくなります。
valは19:12にモニカを

23

C / C ++

導入/チュートリアルのスタイルで記述されたコードの一部...

チュートリアル番号 2:数値を読み取り、数値演算を実行し、結果を印刷します。

//////////////////////////////////////////////////
///////////////////////////////////////////////////
/////                                            //
/////           T  U  T  O  R  I  A  L           //
/////                                            //
///////////////////////////////////////////////////

#include "stdio.h"

int main()
{
    ///////////////////////////////////////////////
    // Local variables (int means integer!!)      /
    int a, b, result;

    ///////////////////////////////////////////////
    // Reading them in                            /
    scanf("%d", &a);
    scanf("%d", &b);

    ///////////////////////////////////////////////
    // Performing an operation, e.g. addition!!!  /
    result = a+b;

    ///////////////////////////////////////////////
    // Why is the next line absolutely mandatory??/
    result = 42;
    printf("The result is: %d", result);

}

result = 42;一見余分なように見える行を削除すると、記述された目的を考慮すると、実際には間違っているため、プログラムは実際には説明のとおりに動作しません。

どうして?

トライグラフが再びストライク!?? /はプリプロセッサによって\に置き換えられ、次の行がコメントに連結されます。= 42結果。はコメントの一部になるため、印刷行を「保存」します。結果= 42。行が削除されると、printf行はコメントに飲み込まれます。一部のコンパイラは警告を出すか、トライグラフをデフォルトとしてオフにし、この例を機能させるにはオンにする必要があります。構文の強調表示もそれを裏切る可能性がありますが、コンパイラーとIDEがあり、それらは賢明なものではありません。


少なくともgccでは、このフラグ(-trigraphs)を追加して、トライグラフを使用することを指定する必要があります。これがないと、gccは警告を発し、3文字表記を無視します。
ガリBN 14年

4
良いですね!私はそれを理解する前にあまりスクロールしなかったことをうれしく思います。あなた>!だけの代わりにそれを開始することにより、あなたのblockquoteをネタバレテキストに変更できます>
きしむオッシファージュ14

@squeamishossifrage:ありがとう、これは私の本来の意図でした>!。私は彼らが書いたように彼らは私のために表示されませんが。興味深いことに、SEパーサーはそれを損なわない:)
vsz 14年

1
私は2番目の私が地元には、見た進行中の何かの卑劣は知っていた"stdio.h"含める代わりに、実際のライブラリーの、<stdio.h>
ブレーデンベスト

1
余計なコメントを見た瞬間に、「トライグラフはどこにあるの?トリグラプが必要だね。あ、そうだ」と声を出して言った。

19

空白

残念ながら、StackExchangeは末尾の空白をすべて削除するため、ここにプログラムを表示できません。同じことがpastebin.comとpastie.orgにも当てはまるため、リンクすることもできません。

もちろん、プログラム全体は「役に立たないように見えます」が、行を削除すると、何か別のことが行われます。


41
ので、しかし幸いな値のものは、失われることはありません全体の言語は無意味です:-)
うるさいossifrage

1
@Timwi「生の貼り付けデータ」ボックスはどうですか?
ブレーデンベスト14年

1
@Timwi私はここでそれをテストしました、そして私はあなたが何を意味するか見ます。ただし、空白以外のテキストを入力すると送信され、未加工のペーストデータは変更されません。例えば、あなたが言って余分なラインに置く「コピーペースト生データをこの行削除」でした
ブレーデンベスト

8
\ tをtに置き換えます。""をsに置き換え、\ nをnに置き換えます
ランチャー14年

7
史上最高のいたずら:実際にコードを記述することなく何かを投稿します。
カズウルフ14

9

JavaScript:

for (var a = 0, b = 4; ++a < b; a++)b+-

2 + 2; // This line is needed, or it will alert twice!
alert(a);

ボディがあるため、それが動作する理由はforあるb+-、ありませんb++b--。したがって、必要な行を削除するとb、の値に追加されます-alert(a)


「それが追加されますbの値alert(a)」:だから、べきではないb+-ことb+=
ゴーランタンドン14

@GaurangTandonいいえ; アイデアは、b++またはのように見えることb--です。
歯ブラシ14

b +-実際にはどういう意味ですか?
Mhmd 14

5
user689 @ b + -2 + 2。そのため、で行を削除すると2 + 2;、と評価されb + -alert(a);ます。
歯ブラシ14

8

C:

#include <stdio.h>
#include <string.h>

int main() {
    int i,sum;
    char s[4];

    /* Add all the integers < 1000 that contain no '0' or '9' */
    sum=0;
    for (i=0; i<1000; i++) {
        sprintf(s,"%d",i);
        if (strchr(s,'0')) goto skip;
        if (strchr(s,'9')) goto skip;
        sum += i;
      skip:
        i = i; /* Don't delete this line! */
    }
    printf("The answer is %d\n",sum);  /* <<< Should be 258948 */
    return 0;
}

行を削除すると、i = i;コードは機能しません。それの訳は...

...実際、コンパイルすらされません。C標準によれば、上記の例のskipのようなラベルはステートメントに関連付けられている必要あります。1つのセミコロンでも十分ですが、行全体を削除すると、ラベルに関連するステートメントがなくなり、コンパイルが失敗します。この回答では、もう少し詳しく説明します。


7

APL

APL関数は次のとおりです。

i_←{
  ⍺←⎕IO ⋄ ⎕IO←⍺
  ⍵⍴⍳×/⍵
}

Jのモナドと同じことを行いi.ます。

      i_ 5 5
 1  2  3  4  5
 6  7  8  9 10
11 12 13 14 15
16 17 18 19 20
21 22 23 24 25

オフセットを与えるオプションの左引数を取ることができます:

      0 i_ 5 5
 0  1  2  3  4
 5  6  7  8  9
10 11 12 13 14
15 16 17 18 19
20 21 22 23 24

ラインは⍺←⎕IO ⋄ ⎕IO←⍺役に立たない(「アサインに見える⎕IOは、割り当てるには⎕IO」)が、最初の部分だけで何の左引数が指定されていない場合、その実際にはそれが何かをしない実行します。

  • no が指定された場合、(global)に設定され⎕IOます。
  • (ローカル)⎕IOに設定

7

C#

Func<int, int> fibo;
fibo = null; //Note that this can be set to *any* Func<int, int> reference.  It doesn't matter.
fibo = x => x < 1 ? 1 : fibo(x-1) + fibo(x-2);

fiboラムダをfiboそれ自体に割り当てる場合でも、変数はラムダ内で使用する前に割り当てる必要があります。(一見役に立たない)割り当てを削除すると、コンパイラエラーが発生します(「未割り当てのローカル変数 'fibo'の使用」)。


null参照例外ではなく、初期化されていない変数コンパイラエラーです。また、宣言は無用ではないため、宣言を独自の行に移動することをお勧めします。
ケンドールフレイ14年

@KendallFrey良い点!一定。
ベン・ライヒ

5

Windowsバッチ:

echo hello
pause
echo world

実行中のプログラムを設定し、ファイルを次のように変更します。

rem test01
pause
echo hello world

コメントを削除またはサイズ変更すると、プログラムの最初のインスタンスが一時停止し、19バイト目以降から解釈を続行するため、混乱が生じます。


コメントはありません。
オリオン

4
REM(発言は)コメントオペレータである- stackoverflow.com/questions/11269338
OJW

4

Java

package stackexchange;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;

public class Curl
{
    public void getUrl(String address)
    {
        try {
            URL url = new URL(address);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setRequestMethod("GET");
            BufferedReader input = new BufferedReader(new InputStreamReader(conn.getInputStream()));

            /* don't remove this line! */
            http://codegolf.stackexchange.com

            while( true ){
                String line = input.readLine();
                if( line==null ) break http;
                System.out.println(line);
            }

            input.close();

        } catch(IOException ex){
            // ignore.
        }
    }

    public static void main(String[] args) {
        Curl curl = new Curl();
        curl.getUrl("http://codegolf.stackexchange.com");
    }
}

これは、URLからWebページを取得する作業プログラムです。驚いたかもしれません

            http://codegolf.stackexchange.com

警告なしでコンパイルします。実際、それなしではプログラムはコンパイルされません。

これは実際にはラベルでありhttp:、その後にコメントが続き//codegolf...ます。ラベルはwhileに適用され、break http;ステートメントで使用されます。


1
いくつかの説明をお願いします。さもなければ、私はあなたの言うことは何でもその行を削除します。
ビル・ウッドガー14年

3

ルビー

require 'prime'

# Given a regular expression, return the smallest prime containing it
# and the substring of the prime that matches it
def smallest_prime_matching_regexp(regexp)
  match = 'this assignment is necessary even though the value is never used'
  prime = Prime.find { |n| match = n.to_s[regexp] }
  return prime, match
end

[ /4/, /1+2/, /[02468]{2,}/ ].each do |regexp|
  prime, match = smallest_prime_matching_regexp(regexp)
  puts "#{regexp.inspect}:\t#{prime} (#{match})"
end

同様のことが最近出てきました。同僚がコードレビュー中に不必要に見える初期化にフラグを立てたので、説明をネタバレブロックの中に入れたいと思いました。だからここでやる。

ブロック内で初期化された変数はそのブロックに対してローカルであるため、この行が必要です。ブロックの外側で初期化すると、値はメソッドスコープにエスケープできます。

そのまま出力:

/4/:    41 (4)
/1+2/:  127 (12)
/[02468]{2,}/:  223 (22)

メソッドの最初の行を削除した出力:

main:Object(NameError)の未定義のローカル変数またはメソッド「match」


1
それが必要なの理由はかなり明白だ...と、とにかく、これを書くためのより良い方法は、単にだろうmatch = Prime.find { |n| n.to_s[regexp] }
ドアノブ

1
それは私が望むことをしません... Prime.find戻りますn(例えば223)、そしてmatchする必要がありますn.to_s[regexp](例えば「22」)。明らかに、必要なものにするために問題を考案しました。
histocrat

ああ、申し訳ありませんが、配列ではなく、呼び出し中findであることに気付きPrimeませんでした。とにかく、その行が必要な理由に気付くのはまだかなり簡単です...
ドアノブ

けっこうだ。たぶん私の同僚はただ観察していなかったのでしょう。
histocrat

ほら 変数宣言はありませんが、Pythonが行うことに対してローカル/非ローカルをデフォルトにする反対のアプローチです。私がRubyを学ぶことに決めたら、それは奇妙に感じるでしょう。
user2357112は

3

PHP

<?php
$some_html_text= <<<EOT
<h1>This is a Header </h1>
<body> This is a body </body>
EOT;
//This is a comment    

ここ\n//This is a commentが必要です。それなしでは、コードは実行されません。

適切に実行するに\nは少なくともcharが必要ですEOT;


3

ジャバスクリプト

var a = function(b) {
    return b;
}

; // This must be here

(function() {
    // more code
}());

セミコロンがなければ、a2番目の関数からの戻り値は、この場合は-になりundefinedます。最初に割り当てられた関数aは、2番目の関数を引数としてすぐに実行されるためbです。


2

COBOL(IBMメインフレーム)

   ID DIVISION. 
   PROGRAM-ID. USELESS. 
   DATA DIVISION. 
   WORKING-STORAGE SECTION. 
   01  W-WHEN-COMPILED              PIC X(8)BX(8) VALUE SPACE.
   PROCEDURE DIVISION. 
       IF W-WHEN-COMPILED EQUAL TO SPACE 
           NEXT SENTENCE 
       END-IF 
       MOVE SPACE                   TO W-WHEN-COMPILED. 
       MOVE WHEN-COMPILED           TO W-WHEN-COMPILED 

       DISPLAY W-WHEN-COMPILED " HELLO WORLD!" 
       GOBACK 
       . 

上記のプログラム(COBOL II以降のIBMメインフレームCOBOL(1985年標準の最初のIBMコンパイラ、おそらく他のIBM COBOLも同様))を実行すると、出力は次のようになります。

02/22/14 13.11.02こんにちは世界!

ただし、3つの役に立たない行「スペースをW-WHEN-COMPILEDに移動」を削除すると、(フィールドはスペースの初期値を持ち、次の命令で他のコンテンツが配置され、とにかく分岐します)プログラムは出力を生成せず、実際には次のメッセージで異常終了(U4038)(クラッシュすることを意味します) :

 IGZ0037S The flow of control in program USELESS proceeded beyond the 
          last line of the program.  From compile unit USELESS at entry 
          point USELESS at compile unit offset +000003AC at entry offset
          +000003AC at address 119003AC. 

(メッセージのコードとテキストはコンパイラーによって異なり、オフセットは実際に使用されるコンパイラーとコンパイルオプションに依存し、アドレスは実行時にプログラムがロードされる場所に依存します)。

その理由はNEXT SENTENCE。これはSecret GO TOです。コンパイラは、ソース内の次のフルストップ/ピリオドを探し出し、次の命令への分岐を生成します。COBOL IIからは、フルストップ/ピリオドの使用が緩和されました。プログラムは、フルストップ/ピリオドで終了する必要があります。この場合、分岐はプログラムの最後から外れています。

両方のプログラムは、100%クリーン(診断メッセージなし、ゼロのリターンコード)でコンパイルします。

この動作は、COBOLへの愚かな「IBM拡張」です。1985規格では、/ NEXT SENTENCE内は許可されていません(代わりに使用されますが、これはノーオペレーションです)。IBMはそれを許可しました-時々ひどいGotchaを引き起こしました。IFEND-IFCONTINUE


2
#include <stdio.h>
#include <stdlib.h>

void strcmp_or_die(char *s, char *t) {
    if(!strcmp(s, t)) {
        printf("Success!\n");
    } else {
        int *ptr = NULL;
        *ptr = 0;
    }
}

int main(void) {
    char blah = '\0'; //segfaults without this line

    char v[2] = "ok";
    strcmp_or_die(v, "ok");
}

単純な文字列オーバーフローの問題。


1
まともなコンパイラーは、「初期化子が多すぎます」という診断を提供します。
ベンフォイト14

どのプラットフォームのセグメンテーション違反はありませblahんか?ここでOpenBSD 5.5 / amd64とシステムgccを使用すると、blah存在するかどうかにかかわらず、セグメンテーション違反は発生しません。コンパイルされたプログラムは、16バイトのスタックスペースを割り当て、「ok」の16ビット値を最初の2バイトにコピーします。初期化されていない3番目のバイトには、運がよければ '\ 0'があります。ある場合blah、それは16番目のバイトにあり、まだ文字列を終了していません。
カーニグ14

2

〜-〜!

これはおそらくここで最も愚かな、最も明白なものです。

'=|hello\|:
'=~!|Useless?\|:
@'[|y|]|n|:

2行目なしでエラーをスローし、それを出力しyます。

バックスラッシュはエスケープ文字ではありません。


言語名はどのように発音しますか?

8
@professorfish~-~!
ティム

1
@professorfishそれは「コメントなし」でしょう。
cjfaure 14年

1

Windowsバッチ

これは、1から10までの数字と、それぞれの後に空の行を出力するバッチファイルです。

@echo off

setlocal EnableDelayedExpansion

set NL=^


rem Previous two lines deliberately left blank for NL to work.

for /l %%a in (1,1,10) do (
    echo %%a!NL!
)

endlocal

pause

これは効果的にダーティハックを利用して、変数内に改行を格納します(遅延展開を使用すると、リンクされた回答のより怖いNL行が取り除かれます)。コメントの上にある2つの完全に役に立たない空白行を削除するか、変更しないと、うまくいきません。


0

troff

Troffは最も素晴らしいテキスト処理システムです。文書に使用します。すぐに使用するにはマクロシステムが必要で、最も有名なのはmsマクロパッケージです。従来の-msオプションを使用して、次のコードをコンパイルしましょう。

.\" -ms macro package
.\" the following line seems to be useless
\& \" print an invisible character
.ad c
.sp |300p \" absolute vertical positionning
.ps 36p
.ft B
My title.
.PP
This is a paragraph.

3行目は役に立たないようで、実際にはマクロパッケージなしでは役に立たないでしょう。2行下に絶対的な垂直配置が続くため、何も印刷しないことは無意味に思えるかもしれません。しかし、この目に見えない文字がなければ、垂直配置は効果がありませんが、理由を説明できるかどうかは確かではありません(議論を一見したい場合は、このスレッドを参照してください)。これにより、新しいユーザーは夢中になりますが、そのトリックは、より実験的なユーザーになじみのあるものになるはずです。

あまり知られていないtroffのお気に入りバージョン(家宝troff)で確認したところ、GNU troffでも同じように動作することは間違いありません。


いいですね、これはLaTeXでも起こります。空のボックスなどがなければ、垂直方向の間隔は適切に機能しません。
オリオン
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.