在看起来没用的程序中写一行


26

编写一些程序(大小无关紧要),然后放置看起来无用的行,但实际上并不是这样-如果将其删除,程序将崩溃或做错事。随意标记注释中未使用的行,或在代码说明中提及它,如下面的示例(当然,在此示例中,实际上不需要该行,仅是示例)。

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

    return 0;
}

由于这是人气竞赛,因此票数最高的解决方案将获胜。


2
为什么示例中的行是必需的?
Gari BN 2014年

3
@GariBN不是:“在此示例中,实际上不需要该行,这只是一个示例。”
elixenide 2014年

9
@EdCottrell很高兴知道...我以为我错过了一些基本的东西……
Gari BN

2
因此这必需的。举个例子。:-)
Florian F

1
我投票结束这个问题是不合时宜的,因为轻率的挑战不再是这个网站上的话题。meta.codegolf.stackexchange.com/a/8326/20469

Answers:


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标签可以发现这里的(在文档131)142页


4
GCC表示“标签只能是声明的一部分,声明不能是声明”。
Vortico

1
我只是在为学校编写的程序中被这个问题所咬。
凯文-恢复莫妮卡

这使得实际程序实际上看起来非常难看:\。
瓦尔说莫妮卡

23

C / C ++

只是一些以介绍/教程风格编写的代码...

教程nr。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行将被注释吞噬。一些编译器可能会发出警告,或可能在默认情况下关闭trigraph,并且必须打开才能使本示例正常工作。语法高亮也可能会背叛它,但是周围有编译器和IDE会让您更明智。


至少在gcc中,您必须通过添加此标志(-trigraph)来指定要使用三字母组合。没有这个,gcc会发出警告并忽略三部曲。
Gari BN 2014年

4
好东西!我很高兴在没有弄清楚之前没有向下滚动太多。您可以通过以>!而不是just 开头的方式将blockquote更改为剧透文本>
吱吱作响的ossifrage,2014年

@squeamishossifrage:谢谢,这是我的初衷,>!并不是每行都使用。我虽然它们在我写它们时不为我显示。有趣的是,SE解析器不会破坏它:)
vsz 2014年

1
我知道第二次看到本地包含内容"stdio.h"而不是实际的图书馆包含内容时就偷偷摸摸地走了,<stdio.h>
Braden Best

1
当我看到多余的评论的那一刻,我大声说:“三部曲在哪里?必须有一个三脚架-啊,是的。”

19

空格

不幸的是,我无法在此处显示程序,因为StackExchange会剥离所有尾随的空格。pastebin.com和pastie.org也是如此,因此我也无法链接到它。

当然,整个程序看起来“没用”,但是如果删除任何行,它会做一些不同的事情。


41
但幸运的是,不会失去任何价值,因为整个语言都是无用的:-)
ossifrage吱吱作响2014年

1
@Timwi“原始粘贴数据”框如何?
Braden Best

1
@Timwi我刚刚在这里进行了测试,我明白了你的意思。但是,如果您放置非空白文本,它将提交,并且原始粘贴数据将保持不变。例如,您可以添加一条额外的行,说“复制原始粘贴数据并删除此行”
Braden Best 2014年

8
用\替换\ t。用s替换“”,用n替换\ n
Cruncher 2014年

7
有史以来最好的恶作剧:发布某些内容而无需实际编写代码。
卡兹·沃尔夫

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);

它工作的原因是因为主体forb+-,不是b++b--; 因此,如果删除所需的行,它将添加到b的值-alert(a)


“这样做会增加b价值alert(a)”:所以,不应该b+-b+=
Gaurang Tandon 2014年

@GaurangTandon否;这个想法是看起来像b++还是b--
牙刷

b +-实际上是什么意思?
Mhmd 2014年

5
@ user689 b + -2 + 2。这就是为什么如果删除带有的行2 + 2;,其结果为b + -alert(a);
牙刷

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)必须与语句关联。即使是单个分号也已足够,但是如果删除整行,则标签将没有关联的语句,并且编译将失败。该答案将更详细地说明。


7

杀伤人员地雷

这是一个APL函数:

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

它的作用与J的monadic相同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

它可以使用可选的left参数,该参数给出偏移量:

      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”),但是第一部分仅在未给出left参数的情况下运行,因此实际上它可以执行以下操作:

  • 如果未给出,则设置为(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即使您正在为lambda分配变量,也必须先分配该变量,然后才能在lambda中使用它fibo。如果删除(似乎无用)分配,则会发生编译器错误(“使用未分配的局部变量'fibo'”)。


这不是空引用异常,而是未初始化的变量编译器错误。另外,最好将声明移到自己的行,因为声明不是没有用的。
Kendall Frey 2014年

@KendallFrey好点!固定。
Ben Reich 2014年

5

Windows批处理:

echo hello
pause
echo world

设置程序运行并将文件修改为:

rem test01
pause
echo hello world

如果删除注释或调整注释大小,则会在程序的第一个实例暂停并随后从第19个字节开始继续解释时造成严重破坏。


我没有看到任何评论。
Orion 2014年

4
REM(注)是注释运营商- stackoverflow.com/questions/11269338
OJW

4

爪哇

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检索网页。您可能会对行感到惊讶

            http://codegolf.stackexchange.com

甚至没有警告就编译。实际上,没有该程序就无法编译。

它实际上是一个标签,http:后跟一个注释//codegolf...。标签适用于while并在break http;语句中使用。


1
请提供一些解释,否则无论您说什么我都会删除该行。
比尔·伍德格

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

啊,对不起,没注意到你打电话findPrime,而不是一个数组。无论如何,仍然很容易注意到为什么需要该行...
Doorknob

很公平。也许我的同事只是不留神。
histocrat

嗯 没有变量声明,而是将本地/非本地默认为Python的相反方法。如果我决定学习Ruby,那将感觉很奇怪。
user2357112支持Monica 2014年

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后至少需要一个字符EOT;


3

JAVASCRIPT

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

; // This must be here

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

如果没有分号,那么a第二个函数的返回值将变为-在这种情况下为undefined。因为最初分配给该函数的函数a将立即以第二个函数作为参数执行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 Mainframe COBOL(1985年标准的第一个IBM编译器,也可能是其他IBM COBOL),则输出为:

2014年2月22日13.11.02您好,世界!

但是,如果您删除了三行没用的行“将空间移至W-WHEN-COMPILED”。(该字段的初始值为空格,并且在下一条指令中放入了其他内容,并且仍然分支了该字段),该程序不产生任何输出,并且实际上出现Abends(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 SENTENCEIF/ END-IFCONTINUE内使用,而是禁止操作)内。IBM允许这样做-有时会造成可怕的混乱。


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
任何体面的编译器都会为您提供“太多的初始化程序”诊断。
Ben Voigt 2014年

没有哪个平台段错误blah?在这里,使用OpenBSD 5.5 / amd64和系统gcc,无论是否blah存在,它都不会发生段错误。编译后的程序分配16个字节的堆栈空间,并将16位值“ ok”复制到前2个字节中。幸运的是,未初始化的第3个字节的值为'\ 0'。如果blah存在,则在第16个字节中,并且仍不终止字符串。
kernigh 2014年

2

〜-〜!

这可能是最愚蠢,最明显的一个。

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

如果没有第二行,它会抛出一个错误,并打印出来y

反斜杠不是转义字符,呵呵。


您如何发音的语言名称?

8
@professorfish~-~!
Timtech

1
@professorfish那将是“无可奉告”。
cjfaure 2014年

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

这有效地利用了肮脏的hack来在变量中存储换行符(使用延迟扩展摆脱了链接的答案中看上去更恐怖的NL行)。如果您删除或以其他方式更改了注释上方的两个看起来完全无用的空白行,那么它将无法正常工作。


0

鳟鱼

Troff是最出色的文本处理系统。我将其用于文档。它需要一个宏系统才能使用,最著名的是ms宏程序包。让我们用classic -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.

第三行似乎无用,并且如果没有宏包,实际上将无用。由于它在下面两行之后是绝对垂直位置,因此之前什么也不打印似乎毫无意义。但是如果没有这个看不见的字符,垂直定位将不会起作用,尽管我不确定我可以解释为什么(如果您想看一下讨论,请参阅此主题)。这使新用户发疯,但是对于更多尝试过的用户,此技巧应该变得熟悉。

刚刚用我最喜欢的troff版本(传家宝troff)进行了检查,但是我很确定它仍然可以与GNU troff一起使用。


不错,这也发生在LaTeX中。没有空的盒子或类似的东西,垂直间距将无法正常工作。
Orion 2014年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.