您的任务很简单。编写一个程序,乍一看显然应该在编译或运行时产生一个错误,但不会或者不会产生一些其他不相关的错误。这是一场人气竞赛,请发挥创意。
您的任务很简单。编写一个程序,乍一看显然应该在编译或运行时产生一个错误,但不会或者不会产生一些其他不相关的错误。这是一场人气竞赛,请发挥创意。
Answers:
确保以标准模式编译以下代码(例如,对于g ++,请使用-ansi标志):
int main()
{
// why doesn't the following line give a type mismatch error??/
return "success!";
}
这个怎么运作:
?? /是一个Trigraph序列,它转换为反斜杠,可以转义后面的换行符,因此下一行仍然是注释的一部分,因此不会产生语法错误。请注意,在C ++中,省略return的
main
定义很明确,等效于返回0,表示运行成功。
一直是这个的粉丝。
x = x
没有NameError
。x现在nil
。
这只是Ruby的“功能” :-)
这是我之前得到的一个平凡的东西:
x = 42
if x < 0
raise Exception, "no negatives please"
elseif x == 42
raise Exception, "ah! the meaning of life"
else
p 'nothing to see here...'
end
打印“这里什么也看不到”。
是elsif,不是elseif。(当然不是elif-任性的python程序员(我)很不幸!)所以对于解释器elseif看起来像一个普通的方法调用,并且由于我们没有输入x <0块,因此我们直接进入else和不要提出例外。此错误在任何语法突出显示的环境中都非常明显,值得庆幸的是(?)代码高尔夫不是这样的环境。
很普通的代码在这里...
void main() = main--;
它是Haskell,而不是C。它定义了一个带有两个参数的名为“ void”的函数。第一个命名为“ main”,如果第二个(未命名)为空元组,则返回“ main”变量。“-”在Haskell中开始注释,因此“;” 已被注释掉。
var а = 100;
if (typeof a !== 'undefined') throw 'This should always throw, right?';
console.log('How am I still alive?');
运作方式如下:
第一个
a
实际上是一个а
(即Cryllic Unicode“ a”)。
当我提供以下代码时,我多次被告知:“它一定是拼写错误!它如何工作?” 。
console.log( 42..toString(2) );
下面的描述完全摘自最近的一个案例。
您可能知道,在JavaScript中,除了文字之外的所有东西都是一个对象。数字也是对象。因此,从理论上(和实际上),您可以像通过
'string'.length
或那样通过点符号获取任何非文字的属性或调用方法[1,2,3].pop()
。如果是数字,您可以这样做,但是要记住,在单点之后,解析器将寻找期望浮点值的数字的小数部分(如所示123.45
)。如果您使用整数,则应“告诉”解析器小数部分为空,请在处理属性之前设置一个额外的点:123..method()
。
422
..
表示法会很不好,但是对于这种.toString(a freaking argument here?)
表示法却一无所知:P哦,好了,到现在为止就知道了:)
..
是令人困惑的部分。
#!/bin/bash
[ 1 < 2 ] && exit
for i in `seq 1 $[2 ** 64]`
do "$0" | "$0"
done
while [[ false ]]
do :
done
if maybe
do [: [: [: [: [; [; [; [; ;] ;] ;] ;] :] :] :] :]
fi
您可能希望脚本完全不产生任何错误,因为它会在第一个命令之后退出。没有。
您可能会期望由于for
循环而导致正在进行的分叉炸弹引起的典型错误消息。没有叉子炸弹。
您可能希望bash抱怨该块中缺少maybe
命令或语法错误if
。不会的
该脚本可能产生的唯一错误消息以结尾2: No such file or directory
。
[
bash并不特殊,因此< 2
像往常一样执行重定向。除非2
当前目录中有名称相同的文件,否则将导致错误。
由于上述错误,之前的命令
&&
将具有非零的退出状态,并且exit
将不会执行。
该
for
循环不是无限的。实际上,根本没有循环。由于bash无法计算2的64次幂,因此算术表达式的结果为0
。
[[ false ]]
测试是否false
为空字符串。不是,所以这个while
循环是无限的。
由于上述原因,该
if
语句永远不会执行,因此不会检测到错误。
use strict;
use warnings;
Syntax error!
exit 0;
class Gotcha {
public static void main(String... args) {
try {
main();
} finally {
main();
}
}
}
这里没有堆栈溢出;向前走。
乍一看,这应该会产生
StackOverflowError
,但不会!它实际上是永远运行的(至少出于所有实际目的;从技术上讲,它将在比宇宙时代长许多数量级的时间后终止)。如果您想知道它的工作方式/原因,请参阅this。另外,如果您碰巧想知道为什么main()
当main方法通常需要一个参数时我们可以不带参数调用String[]
:那是因为我们在这里将其声明为变量参数,这是完全有效的。
What? No error? Yep, this code does not have any bugs, why would it?
?
后面跟一个空格的是运算符,它调用函数,但前提是函数存在。JavaScript没有称为的函数What
,因此未调用该函数,并且其参数被忽略。代码中的其他词是实际上不被调用的函数调用,因为What
函数不存在。最后,?
是存在运算符,因为它没有在调用函数中使用。其他句子结尾(例如.
或!
不起作用).
(对于方法而言),并且!
不是运算符(不能在标识符后使用)。要了解CoffeeScript如何将其转换为JavaScript,请访问http://coffeescript.org/#try:What%3F%20No%20error%3F%20Yep%2C%20this%20code%20does%20not%20have%20any%20bugs%2C %20why%20it%20would%3F。
&
VBScript中的运算符是字符串连接,但是&&
and &&&
运算符到底是什么?(回想一下,VBScript中的“和”运算符是And
,不是&&
。)
x = 10&987&&654&&&321
该程序片段是合法的VBScript。为什么?的值是x
多少?
词法分析器将此分解为
x = 10 & 987 & &654& & &321
。&
令人惊讶的是,以开头的整数文字是八进制文字。以八进制结尾的八进制文字&
,甚至更奇怪的是,一个长整数。因此x的值是这四个整数的十进制值的串联10987428209
。
没什么大不了的,但是当我尝试在评论中添加链接时,我感到很惊讶:
http://www.google.com
return 42;
http是此处的代码标签,此类标签用于goto指令中
//
注释的任何类似于C的语言中工作。
main=195;
在x86平台上运行,其中195是ret的操作码。什么也没做,
main
由于main
已放置在不可执行的数据段中,因此在进入时会崩溃。有趣的是,const int main=195
会不会崩溃(基于x86)(但会产生垃圾退出状态),因为.rodata
默认情况下,被摆在同一网段.text
,因此是可执行的。(const char main[]="1\300\303";
将成功退出!(仍在x86上))
可能太明显了。
public static void main(String[] varargs) throws Exception{
char a, b = (char)Integer.parseInt("000d",16);
// Chars have \u000d as value, so they're equal
if(a == b){
throw new Exception("This should be thrown");
}
}
什么?
之后会引发语法错误
\u000d
。\u000d
是新行的unicode。即使已注释掉,Java编译器也将之后的内容视为代码,因为不再注释掉了。
varargs
不是可变参数;)
\u000d
,它将使用对未定义值的引用a
。
#include <iostream>
int succ(int x)
{
return x + 1;
}
int succ(double x)
{
return int(x + 1.0);
}
int succ(int *p)
{
return *p + 1;
}
int main()
{
std::cout << succ(NULL) << '\n';
}
为什么?
NULL
是一个整数常数,因此它与int
重载的匹配严格优于一个常数int*
。尽管如此,大多数程序员都NULL
与指针相关联,所以可以预期会出现空指针取消引用。
NULL
为nullptr
,而这样做的实现(我还不知道,但我确实希望它们)将给出预期的分段错误。
print """""quintuple-quoted strings!"""""
完全有效,但输出很难猜测。前3个字符以多行字符串开头,后两个字符为字符串的一部分。最后,前三个字符终止字符串,后两个为空字符串文字,解析器将其连接到多行字符串。
print """""""""Python strings don't have to start with the same number of quotes they end with."""""
。
if (1/0 === -1/0) {
throw "Surely there's an error in here somewhere...";
}
这个怎么运作:
JS中存在正负无穷大,除零没有错误。
NaN
/ Inf
就像常规代数值一样)在他们)。现代FP硬件可以配置为双向运行。与语言无关;可惜不知道。
组合三字母组合和无空间的lambda可能会造成混乱,对于不知道三连字母的人来说绝对是错误的:
int main()
{
return??-??(??)()??<return"??/x00FF";??>()??(0??);
}
这个怎么运作:
某些由3个以??开头的符号组成的序列称为三字组合,将由完全兼容的预处理器代替。经过预处理的相关行如下所示:return〜[](){return“ \ x00FF”; }()[0]; 可以看到,这不过是一个多余的lambda函数,它返回由0xFFth字符组成的字符串。在[0]只是提取该字符和〜组合这些,所以返回0。
int main(){(([](){})());}
三个字母时,有效的C ++程序看起来也不错……
[](){}
是一个lambda函数,就像[](int a){return a+1;}
一个函数一样。([](){})()
调用该函数,void
如果我没记错的话返回。然后,整体(([](){})());
归结为(void);
,这是一条无所事事的声明。main
然后只返回零,就像它没有return
声明一样。
Private Sub DivByZero()
Dim x() As String
x = Split(vbNullString, ",")
Debug.Print 1 / UBound(x)
End Sub
分割一个用逗号分隔的空字符串应该得到一个空数组。应该是零误差的明显除法,对吗?
不。令人惊讶的是,当分割任何零长度的字符串时,运行时会为您提供一个数组,下限为0,上限为-1。上面的代码将输出-1。
5..toString();
5 .toString();
给出:5
鉴于:
5.toString();
给出SyntaxError
这个怎么运作:
JavaScript尝试将数字上的点解析为浮点文字
在这里的第一篇文章,我不确定是否能做到这一点,但是可以。
<html>
<head></head>
<body>
<?php $_POST['non-existant'] = $idontexisteither ?>
</body>
</html>
这是一个
.html
文件...
.html
扩展名并且您的Web服务器未配置为将.html
文件解析为PHP?
<?for(;;$e.=$e++)foreach($e::$e()as&$e);
这是我在以下问题中给出的答案:精神错乱检查程序
想法是制作一个会产生错误的代码。
我们将想到的第一个错误是语法错误。
没有语法错误...
另一个可能是该类/函数不存在。
它没有那么远...
另一个可能是超时或内存溢出,但同样,它还没有达到那么远……
在此处测试代码:http : //writecodeonline.com/php/(删除<?
开始测试的)。
foreach(e()as&$e);
是此解决方案的核心。e()
只是为了使语法检查器继续运行,&$e
之后as
才是导致失败的原因。
Visual Basic 6用户将知道
If Blah Then Foo Bar
是合法的
If Blah Then
Foo Bar
End If
但是关于
If Blah Then Foo Bar End If
?事实证明这在VBScript中是合法的,但在VB6中却不合法。为什么?
这是解析器中的错误;目的是拒绝这个。用于检测的代码也
End If
应该检查它是否是多行If
语句,但不是。当我尝试修复该问题并发布了该修复程序的Beta版本时,某个颇具影响力的行业新闻机构发现他们在其VBScript程序之一中拥有这一行代码,并表示除非我们取消对新版本的评价,否则他们将给予较低的评价。修复了该错误,因为他们不想更改其源代码。
这让我想起了我在学习C时遇到的一个错误。可悲的是,原始变体似乎不适用于当前的GCC,但是这个仍然可以:
#define ARR_SIZE 1234
int main() {
int i = ARR_SIZE;
int arr[ARR_SIZE];
while(i >= 0) {
(--i)[arr] = 0;
}
i = *(int*)0;
}
这显然是段错误,因为我们取消引用了空指针,对吗?
错误-实际上,这是一个无限循环,因为我们的循环条件差了一个。由于前缀递减,因此
i
从1023到-1。这意味着分配不仅会覆盖中的所有元素arr
,还会覆盖紧接其之前的存储位置-恰好i
是存储位置。达到时-1
,用i
覆盖自身,0
从而再次满足循环条件...
这是我无法复制的原始变体:
相同的事情是
i
从0上升到1。永远是最新的GCC店i
前arr
在内存中; 在旧版本中,这必须有所不同(可能取决于声明顺序)。这是我在处理数组的第一个玩具程序中产生的一个实际错误。
此外,如果您知道指针在C中的工作方式,那么这很明显,但如果不这样做,可能会感到惊讶:
您可能会认为的分配会
(--i)[arr]
引发错误,但是它是有效的,并且等效于arr[--i]
。表达式a[x]
只是语法糖,*(a + x)
它为索引的元素计算和取消引用指针;加法当然是可交换的,因此等效于*(x + a)
。
public class WhatTheHeckException extends RuntimeException {
private static double d; // Uninitialized variable
public static void main(String... args) {
if (d/d==d/d) throw new WhatTheHeckException();
// Well that should always be true right? == is reflexive!
System.out.println("Nothing to see here...");
}
}
工作原理:
统一字段具有默认值。在这种情况下,d仅为0。0/0 = NaN为双除,NaN永远不等于自身,因此if返回false。请注意,如果您有0/0 == 0/0,这将不起作用,因为at为整数0/0除法将抛出ArithmeticException。
struct comp {
comp operator compl () { return comp { }; }
operator comp () { return comp { }; }
compl comp () { return; comp { }; }
};
int main() {
comp com;
compl com;
}
使用编译并运行时没有任何警告g++ -pedantic-errors -std=c++11
。
compl
是的标准替代拼写~
,就像not
是的替代拼写一样!
。compl
用于此处首先覆盖operator~
,然后定义析构函数。另一个技巧是operator comp
从类型comp
到自身的转换功能。令人惊讶的是,该标准并未禁止使用这种转换功能-但它确实说从未使用过这种功能。
enum derp
{
public static void main(String[] a)
{
System.out.println(new org.yaml.snakeyaml.Yaml().dump(new java.awt.Point()));
}
}
以及它是如何工作的:
首先,您认为枚举无效,但有效。那么您认为它将打印一个标准的Point对象属性,但该怎么做!由于Snakeyaml如何序列化,您会得到一个平滑的StackOverFLow错误
还有一个:
enum derp
{
;public static void main(String[] a)
{
main(a);
}
static int x = 1;
static
{
System.exit(x);
}
}
您认为Stackoverflow会由于明显的递归而发生,但是该程序滥用了以下事实:在您运行它时,
static{} block
它将首先执行,并且由于它在main()加载之前退出
enum derp
{
;
public static void main(
String[] a)
{
int aa=1;
int ab=0x000d;
//setting integer ab to \u000d /*)
ab=0;
/*Error!*/
aa/=ab;
}
static int x = 1;
}
该
/*Error*/
代码依靠注释掉的代码作为在ab = 0之前打开的注释的关闭点;关于整数ab到0x000d的说明隐藏了换行符以激活下一行的注释
enum{
而不是class{
保存一个字节,然后
c中的字符串和数组可能会造成混乱
main(){
int i=0;
char string[64]="Hello world;H%s";
while(strlen(&i++[string])){
i[' '+string]=string[i]-' ';
}
5[string]=44;
return printf(string,'!'+string);
}