Nhiệm vụ của bạn rất đơn giản. Viết chương trình rõ ràng sẽ tạo ra lỗi ngay từ cái nhìn đầu tiên khi được biên dịch hoặc chạy, nhưng không hoặc không tạo ra một số lỗi không liên quan khác. Đây là một cuộc thi phổ biến, vì vậy hãy sáng tạo.
Nhiệm vụ của bạn rất đơn giản. Viết chương trình rõ ràng sẽ tạo ra lỗi ngay từ cái nhìn đầu tiên khi được biên dịch hoặc chạy, nhưng không hoặc không tạo ra một số lỗi không liên quan khác. Đây là một cuộc thi phổ biến, vì vậy hãy sáng tạo.
Câu trả lời:
Đảm bảo rằng bạn biên dịch mã sau trong chế độ tuân thủ tiêu chuẩn (ví dụ: đối với g ++, hãy sử dụng cờ -ansi):
int main()
{
// why doesn't the following line give a type mismatch error??/
return "success!";
}
Làm thế nào nó hoạt động:
?? / là một chuỗi ba chữ được dịch thành dấu gạch chéo ngược thoát khỏi dòng mới sau đây, vì vậy dòng tiếp theo vẫn là một phần của nhận xét và do đó sẽ không tạo ra lỗi cú pháp. Lưu ý rằng trong C ++, bỏ qua trả về
main
được xác định rõ và tương đương với trả về 0, biểu thị một lần chạy thành công.
Luôn luôn là một fan hâm mộ của điều này.
x = x
Không NameError
. x tại là nil
.
Đây chỉ là một "tính năng" của Ruby :-)
Đây là một thứ trần tục hơn mà tôi đã nhận được trước đây:
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
In "không có gì để xem ở đây."
Nó elsif , không elseif . (và nó chắc chắn không elif - khốn cho các lập trình viên python bướng bỉnh (tôi)!) Vì vậy, để người phiên dịch elseif trông giống như một cuộc gọi phương pháp thông thường, và vì chúng ta không nhập x <0 khối, chúng tôi đi thẳng vào khác và đừng đưa ra một ngoại lệ. Lỗi này là vô cùng rõ ràng trong bất kỳ môi trường làm nổi bật cú pháp, rất may (?) Golf code không phải là một môi trường như vậy.
Mã khá bình thường ở đây ...
void main() = main--;
Đó là Haskell, không phải C. Nó định nghĩa một hàm có tên là "void" có hai đối số. Cái đầu tiên được đặt tên là "chính" và nếu cái thứ hai (chưa được đặt tên) là một tuple trống, nó sẽ trả về biến "chính". "-" bắt đầu nhận xét bằng Haskell, vì vậy dấu ";" được bình luận ra.
var а = 100;
if (typeof a !== 'undefined') throw 'This should always throw, right?';
console.log('How am I still alive?');
Đây là cách nó hoạt động:
Đầu tiên
a
thực sự là mộtа
(nghĩa là Unicode Cryllic "a").
Khi tôi đang cung cấp mã sau đây, tôi đã nói nhiều lần "Nó phải là một lỗi đánh máy! Làm thế nào nó có thể hoạt động?" .
console.log( 42..toString(2) );
Mô tả dưới đây được sao chép chính xác từ một trong những trường hợp gần đây .
Như bạn có thể biết, trong JavaScript mọi thứ trừ chữ đều là một đối tượng. Số là đối tượng là tốt. Vì vậy, về mặt lý thuyết (và thực tế), bạn có thể nhận được các thuộc tính hoặc gọi các phương thức của bất kỳ chữ nào thông qua ký hiệu dấu chấm, như bạn làm
'string'.length
hoặc[1,2,3].pop()
. Trong trường hợp số bạn có thể làm tương tự nhưng bạn nên nhớ rằng sau một dấu chấm duy nhất, trình phân tích cú pháp sẽ tìm một phần phân số của số có giá trị float (như trong123.45
). Nếu bạn sử dụng một số nguyên, bạn nên "thông báo" cho trình phân tích cú pháp rằng một phần phân số trống, đặt dấu chấm phụ trước khi xử lý thuộc tính :123..method()
.
422
..
ký hiệu này, nhưng hoàn toàn không biết gì về .toString(a freaking argument here?)
ký hiệu: P Oh tốt, đã tìm ra nó ngay bây giờ :)
..
là phần khó hiểu.
#!/bin/bash
[ 1 < 2 ] && exit
for i in `seq 1 $[2 ** 64]`
do "$0" | "$0"
done
while [[ false ]]
do :
done
if maybe
do [: [: [: [: [; [; [; [; ;] ;] ;] ;] :] :] :] :]
fi
Bạn có thể mong đợi tập lệnh không tạo ra bất kỳ lỗi nào, vì nó thoát ra sau lệnh đầu tiên. Nó không.
Bạn có thể mong đợi các thông báo lỗi điển hình gây ra bởi một quả bom ngã ba đang diễn ra do for
vòng lặp. Không có bom ngã ba.
Bạn có thể mong đợi bash phàn nàn về maybe
lệnh bị thiếu hoặc toàn bộ lỗi cú pháp bên trong if
khối. Nó sẽ không.
Thông báo lỗi duy nhất mà tập lệnh có thể tạo ra kết thúc bằng 2: No such file or directory
.
[
không đặc biệt đối với bash, do đó< 2
, thực hiện, như thường lệ, chuyển hướng. Trừ khi có một tệp có tên2
trong thư mục hiện tại, điều này sẽ gây ra lỗi.
Do lỗi đó ở trên, lệnh trước
&&
sẽ có trạng thái thoát khác không vàexit
sẽ không được thực thi.
Các
for
vòng lặp không phải là vô hạn. Trong thực tế, không có vòng lặp nào cả. Vì bash không thể tính được lũy thừa thứ 64 của 2, kết quả của biểu thức số học là0
.
[[ false ]]
kiểm tra nếufalse
là một chuỗi null. Không phải vậy, nênwhile
vòng lặp này là vô hạn.
Do những điều trên,
if
câu lệnh không bao giờ được thực thi, do đó không có lỗi nào được phát hiện.
use strict;
use warnings;
Syntax error!
exit 0;
Nguồn và giải thích: https://stackoverflow.com/questions/11695110
class Gotcha {
public static void main(String... args) {
try {
main();
} finally {
main();
}
}
}
Không có chồng tràn ở đây; di chuyển dọc.
Thoạt nhìn, điều này sẽ tạo ra một
StackOverflowError
, nhưng nó không! Nó thực sự chỉ chạy mãi mãi (ít nhất là cho tất cả các mục đích thực tế; về mặt kỹ thuật, nó sẽ chấm dứt sau một thời gian nhiều đơn đặt hàng lớn hơn tuổi của vũ trụ). Nếu bạn muốn biết làm thế nào / tại sao điều này hoạt động, xem điều này . Ngoài ra, nếu bạn tình cờ tự hỏi tại sao chúng ta có thể gọimain()
mà không có đối số khi phương thức chính thường cần mộtString[]
đối số: đó là vì chúng ta đã tuyên bố nó là đối số biến ở đây, điều này hoàn toàn hợp lệ.
What? No error? Yep, this code does not have any bugs, why would it?
?
theo sau là khoảng trắng là toán tử gọi hàm, nhưng chỉ khi nó tồn tại. JavaScript không có hàm được gọiWhat
, do đó hàm không được gọi và các đối số của nó đơn giản bị bỏ qua. Các từ khác trong mã là các lệnh gọi hàm thực sự không được gọi, vìWhat
hàm không tồn tại. Cuối cùng,?
là toán tử tồn tại, vì nó không được sử dụng trong chức năng gọi. Các kết thúc câu khác, chẳng hạn như.
hoặc!
sẽ không hoạt động, như.
đối với các phương thức và!
không phải là toán tử (không thể được sử dụng sau một mã định danh). Để đọc cách CoffeeScript chuyển đổi mã này thành JavaScript, hãy truy cập http://coffeescript.org/#try:What%3F%20No%20error%3F%20Yep%2C%20this%20code%20does%20not%20have%20any%20bugs%2C % 20why% 20it% 20would% 3F .
Các &
nhà điều hành trong VBScript là chuỗi nối nhưng những gì trên trái đất là &&
và &&&
các nhà khai thác? (Hãy nhớ rằng toán tử "và" trong VBScript là And
không &&
.)
x = 10&987&&654&&&321
Đoạn chương trình đó là VBScript hợp pháp. Tại sao? Và giá trị của là x
gì?
Các lexer phá vỡ điều này như
x = 10 & 987 & &654& & &321
. Một chữ nguyên bắt đầu bằng&
, thật kỳ lạ, một chữ bát phân. Một số bát phân kết thúc bằng&
, thậm chí kỳ lạ hơn, là một số nguyên dài. Vì vậy, giá trị của x là phép nối các giá trị thập phân của bốn số nguyên đó :10987428209
.
Không phải là một vấn đề lớn, nhưng nó đã làm tôi ngạc nhiên khi cố gắng đặt một liên kết bên trong một bình luận:
http://www.google.com
return 42;
http là nhãn mã ở đây, các nhãn như vậy được sử dụng trong hướng dẫn goto
//
bình luận.
class Foo
{
static void Main(string[] args)
{
Bar();
}
static IEnumerable<object> Bar()
{
throw new Exception("I am invincible!");
yield break;
}
}
Bởi vì
Bar
phương thức thực hiện ayield
, phương thức không thực sự chạy khi được gọi, nó trả về một liệt kê mà khi lặp lại, s sẽ chạy phương thức.
main=195;
Hoạt động trên nền tảng x86, trong đó 195 là opcode cho ret. Không lam gi cả,
main
vì main
đã được đặt trong phân đoạn dữ liệu, không thể thực thi được. Thật thú vị, const int main=195
sẽ không sụp đổ (trên x86) (nhưng sẽ tạo ra trạng thái thoát rác) vì .rodata
theo mặc định được đặt trong cùng phân khúc .text
và do đó có thể thực thi được. ( const char main[]="1\300\303";
sẽ thoát thành công! (vẫn trên x86))
Có lẽ là quá rõ ràng.
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");
}
}
Gì?
Ném một lỗi cú pháp sau
\u000d
.\u000d
là unicode cho một dòng mới. Mặc dù nó được nhận xét, trình biên dịch Java coi mã này là mã vì nó không được nhận xét nữa.
varargs
không phải là varargs;)
\u000d
, nó sẽ sử dụng một tham chiếu đến giá trị không xác định 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';
}
Tại sao?
NULL
là một hằng số intergal, vì vậy nó phù hợp vớiint
tình trạng quá tải hoàn toàn tốt hơn so vớiint*
một. Tuy nhiên, hầu hết các lập trình viên đãNULL
liên kết với các con trỏ, do đó, có thể dự kiến một con trỏ null null.
NULL
là nullptr
và các triển khai thực hiện điều đó (chưa có gì tôi biết, nhưng tôi thực sự mong đợi chúng) sẽ đưa ra lỗi phân đoạn dự kiến.
print """""quintuple-quoted strings!"""""
Hoàn toàn hợp lệ, nhưng đầu ra là khó đoán. 3 ký tự đầu tiên bắt đầu một chuỗi nhiều dòng và hai ký tự tiếp theo là một phần của chuỗi. Cuối cùng, ba ký tự đầu tiên chấm dứt chuỗi và hai ký tự cuối cùng là một chuỗi ký tự trống được trình phân tích cú pháp nối với chuỗi đa dòng .
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...";
}
Làm thế nào nó hoạt động:
Có vô cực tích cực và tiêu cực trong JS, và không có lỗi khi chia cho số không.
NaN
/ Inf
giống như các giá trị đối số thông thường với toán học được xác định rõ về họ). Phần cứng FP hiện đại có thể được cấu hình để vận hành cả hai cách. Ngôn ngữ bất khả tri; xấu hổ không biết.
Việc trộn các chữ viết tay và lambdas không gian có thể khá khó hiểu và chắc chắn trông có vẻ không ổn đối với những người không biết về các bức thư:
int main()
{
return??-??(??)()??<return"??/x00FF";??>()??(0??);
}
Làm thế nào nó hoạt động:
Một số trình tự bao gồm 3 ký hiệu, bắt đầu bằng ??, được gọi là các biểu tượng và sẽ được thay thế bằng một bộ tiền xử lý tuân thủ đầy đủ. Được xử lý trước, dòng trong câu hỏi trông như sau: return ~ [] () {return "\ x00FF"; } () [0]; Như mọi người có thể thấy, đây không là gì ngoài hàm lambda thừa, trả về một chuỗi bao gồm ký tự 0xFFth. Các [0] chỉ trích nhân vật đó và ~ nots nó, vì vậy 0 được trả về.
int main(){(([](){})());}
cũng có thể trông rất tuyệt khi được phân tích ...
[](){}
là một hàm lambda, giống như [](int a){return a+1;}
là một. ([](){})()
gọi hàm đó, trả về void
nếu tôi không nhầm. Toàn bộ (([](){})());
sau đó sôi lên (void);
, đó là một tuyên bố không làm gì. main
sau đó chỉ trả về 0, giống như nó không có return
câu lệnh.
Private Sub DivByZero()
Dim x() As String
x = Split(vbNullString, ",")
Debug.Print 1 / UBound(x)
End Sub
Việc tách một chuỗi được phân cách bằng dấu phẩy trống sẽ tạo ra một mảng trống. Nên là một sự phân chia rõ ràng bởi lỗi không, phải không?
Không. Đáng ngạc nhiên, khi bất kỳ chuỗi có độ dài bằng 0 nào được phân chia, bộ thực thi cung cấp cho bạn một mảng có giới hạn dưới là 0 và giới hạn trên là -1. Đoạn mã trên sẽ xuất -1.
5..toString();
5 .toString();
Tặng: 5
Trong khi:
5.toString();
Cung cấp SyntaxError
Làm thế nào nó hoạt động:
JavaScript cố phân tích dấu chấm trên một số dưới dạng dấu phẩy động
Bài đăng đầu tiên ở đây, tôi không chắc tôi có nhận được điều này hay không, nhưng ở đây đi.
<html>
<head></head>
<body>
<?php $_POST['non-existant'] = $idontexisteither ?>
</body>
</html>
Đó là một
.html
tập tin ...
.html
phần mở rộng và máy chủ web của bạn không được cấu hình để phân tích .html
các tệp như PHP?
<?for(;;$e.=$e++)foreach($e::$e()as&$e);
Đây là câu trả lời tôi đưa ra trong câu hỏi này: Chương trình kiểm tra sự điên rồ
Ý tưởng là tạo ra một mã tạo ra lỗi.
Lỗi đầu tiên mà chúng ta sẽ nghĩ đến là lỗi cú pháp.
Không có lỗi cú pháp ...
Khác là lớp / hàm không tồn tại.
Nó không chạy xa đến thế ...
Khác sẽ là hết thời gian hoặc tràn bộ nhớ, nhưng, một lần nữa, nó không đạt đến mức đó ...
Kiểm tra mã ở đây: http://writecodeonline.com/php/ (xóa <?
phần đầu để kiểm tra).
foreach(e()as&$e);
là cốt lõi của giải pháp này. e()
chỉ để giữ cho trình kiểm tra cú pháp hoạt động và &$e
sau đó as
là nguyên nhân gây ra lỗi.
Người dùng Visual Basic 6 sẽ biết rằng
If Blah Then Foo Bar
là hợp pháp, như là
If Blah Then
Foo Bar
End If
Nhưng những gì về
If Blah Then Foo Bar End If
? Hóa ra đó là hợp pháp trong VBScript nhưng không phải trong VB6. Tại sao?
Đó là một lỗi trong trình phân tích cú pháp; ý định là để từ chối điều này. Mã phát hiện
End If
được cho là cũng sẽ kiểm tra xem đó có phải làIf
câu lệnh nhiều dòng hay không. Khi tôi cố gắng sửa nó và gửi bản beta với bản sửa lỗi, một tổ chức tin tức trong ngành có ảnh hưởng nhất định đã phát hiện ra rằng họ có dòng mã này trong một trong các chương trình VBScript của họ và nói rằng họ sẽ xếp hạng phiên bản mới trừ khi chúng tôi không Đã sửa lỗi, vì họ không muốn thay đổi mã nguồn.
Điều này nhắc nhở tôi về một lỗi tôi gặp phải khi tôi học C. Đáng buồn là biến thể ban đầu dường như không hoạt động với GCC hiện tại, nhưng lỗi này vẫn xảy ra:
#define ARR_SIZE 1234
int main() {
int i = ARR_SIZE;
int arr[ARR_SIZE];
while(i >= 0) {
(--i)[arr] = 0;
}
i = *(int*)0;
}
Điều này rõ ràng là segfaults bởi vì chúng tôi bỏ qua một con trỏ null, phải không?
Sai - thực ra, đó là một vòng lặp vô hạn vì điều kiện vòng lặp của chúng ta bị tắt bởi một. Do giảm tiền tố,
i
chạy từ 1023 đến -1. Điều này có nghĩa là việc gán ghi đè không chỉ tất cả các thành phầnarr
, mà cả vị trí bộ nhớ trực tiếp trước nó - điều này xảy ra là nơii
được lưu trữ. Khi đạt tới-1
,i
ghi đè lên chính nó0
và do đó điều kiện vòng lặp được đáp ứng lại ...
Đây là biến thể ban đầu mà tôi không thể tái tạo nữa:
Điều tương tự cũng hoạt động với việc
i
đi lên từ 0 và bị tắt bởi một. GCC mới nhất luôn lưu trữi
trước đóarr
trong bộ nhớ; cái này phải khác ở các phiên bản cũ hơn (có thể tùy theo thứ tự khai báo). Đó là một lỗi thực tế tôi tạo ra trong một trong những chương trình đồ chơi đầu tiên của tôi liên quan đến mảng.
Ngoài ra, điều này là hiển nhiên nếu bạn biết cách con trỏ hoạt động trong C, nhưng có thể gây ngạc nhiên nếu bạn không:
Bạn có thể nghĩ rằng bài tập
(--i)[arr]
đưa ra một lỗi, nhưng nó hợp lệ và tương đương vớiarr[--i]
. Một biểu thứca[x]
chỉ là đường cú pháp để*(a + x)
tính toán và hủy bỏ con trỏ đến phần tử được lập chỉ mục; việc bổ sung tất nhiên là giao hoán và do đó tương đương với*(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...");
}
}
Tại sao điều này hoạt động:
Các trường đơn vị có giá trị mặc định. Trong trường hợp này d chỉ là 0 . 0/0 = NaN trong phép chia kép và NaN không bao giờ bằng chính nó, do đó, nếu trả về false. Lưu ý rằng điều này sẽ không hoạt động nếu bạn có 0/0 == 0/0 , vì tại đó sẽ là số nguyên 0/0 chia sẽ NÊN ném một số học ngoại lệ .
struct comp {
comp operator compl () { return comp { }; }
operator comp () { return comp { }; }
compl comp () { return; comp { }; }
};
int main() {
comp com;
compl com;
}
Biên dịch và chạy mà không có bất kỳ cảnh báo với g++ -pedantic-errors -std=c++11
.
compl
là một cách viết thay thế tiêu chuẩn cho~
, giống nhưnot
là một thay thế cho!
.compl
được sử dụng ở đây để ghi đè đầu tiênoperator~
và sau đó xác định hàm hủy. Một mẹo khác làoperator comp
chức năng chuyển đổi từ loạicomp
sang chính nó. Đáng ngạc nhiên là tiêu chuẩn không cấm chức năng chuyển đổi như vậy - nhưng nó nói rằng chức năng đó không bao giờ được sử dụng.
function[:(](["):"]):[:(]=["):"]:
end function
msgbox getref(":(")(":)")
'Output: :)
Những gì nó làm:
Tên hàm, tên phụ và biến trong VBScript có thể là bất cứ thứ gì nếu bạn sử dụng dấu ngoặc vuông. Kịch bản lệnh này tạo một hàm được gọi
:(
và một đối số"):"
nhưng vì chúng không tuân theo quy ước đặt tên thông thường nên chúng được bao quanh bởi dấu ngoặc vuông. Giá trị trả về được đặt thành giá trị tham số. Một dấu hai chấm bổ sung được sử dụng để có được mọi thứ trên một dòng. Câu lệnh Msgbox nhận được tham chiếu đến hàm (nhưng không cần dấu ngoặc) và gọi nó bằng một nụ cười:)
tham số là .
Thật ra tôi đã bắt gặp mình làm sai điều đó :)
public static object Crash(int i)
{
if (i > 0)
return i + 1;
else
return new ArgumentOutOfRangeException("i");
}
public static void Main()
{
Crash(-1);
}
ném , không trở về .
enum derp
{
public static void main(String[] a)
{
System.out.println(new org.yaml.snakeyaml.Yaml().dump(new java.awt.Point()));
}
}
Và cách thức hoạt động của nó:
Firs bạn nghĩ Enum không hợp lệ nhưng nó hợp lệ; sau đó bạn nghĩ rằng nó sẽ in một thuộc tính đối tượng Điểm tiêu chuẩn nhưng Gotcha! do cách Snakeyaml tuần tự hóa, bạn gặp phải lỗi StackOverFLow mượt mà
Và một số khác:
enum derp
{
;public static void main(String[] a)
{
main(a);
}
static int x = 1;
static
{
System.exit(x);
}
}
bạn nghĩ rằng một Stackoverflow sẽ xảy ra do sự đệ quy rõ ràng nhưng chương trình lạm dụng thực tế là khi bạn chạy nó, nó
static{} block
sẽ được thực thi trước và do nó thoát ra trước khi tải 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;
}
cái này dựa vào
/*Error*/
mã được đặt ra đó làm điểm đóng cho nhận xét được mở trước ab = 0; phần giải thích về số nguyên ab đến 0x000d ẩn dòng mới để kích hoạt nhận xét của dòng tiếp theo
enum{
thay vì class{
lưu một byte sau đó
Chuỗi và mảng trong c có thể khá khó hiểu
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);
}