最奇怪的语言特征

Tho*_*ini 975 language-agnostic programming-languages

在您看来,您遇到的最令人惊讶,奇怪,奇怪或真正的"WTF"语言功能是什么?

每个答案只能有一个功能.

Eda*_*aor 1860

在C中,数组可以像这样索引:

a[10]
Run Code Online (Sandbox Code Playgroud)

这很常见.

然而,鲜为人知的形式(确实有效!)是:

10[a]
Run Code Online (Sandbox Code Playgroud)

这意味着与上述相同.

  • 这是因为[10]表示*(a + 10)...而10 [a]表示*(10 + a):) (758认同)
  • 或者,更有用的是,"0123456789abcdef"[x&0xf] (167认同)
  • 别忘了"Hello World"[i].或者我["Hello World"] (77认同)
  • @frunsi:它总是*按预期工作.指针添加与地址上的简单整数添加不同.它是可交换的*无论*有多大是有问题的类型. (17认同)
  • @mcv - a [10]与"*(a + 10)"相同,其中表达式"a + 10"是指针算术(并且因为a是短的,在你的例子中,+ 10表示'从'开始a的地址,移动10个短路,即20个字节').表达式10 [a]被解释为"*(10 + a)",其中"10 + a"也是*指针算术,并且以完全相同的方式处理. (12认同)
  • 深入了解一下:http://stackoverflow.com/questions/381542/in-c-arrays-why-is-this-true-a5-5a (8认同)
  • frunsi:在这个答案中,代码片段没有使用`number [array]`格式:索引这样的字符串根本不奇怪. (5认同)
  • 伙计们,伙计们!令人惊讶的是,这种疯狂的语法实际上是有用的... http://stackoverflow.com/questions/469696/what-is-your-most-useful-cc-utility/470221#470221 (5认同)
  • 我不认为它是一个特征 - 就像暴露C的核心一样.它完全是关于指针和直接到达内存的尽可能少的间接.有点漂亮,真的. (5认同)
  • @Edan Moar:如果你想参加混淆的C比赛(http://www.ioccc.org/),这是非常宝贵的;) (4认同)
  • Loadmaster:`[!! flag]"FT"`语法无效. (3认同)
  • 应该注意的是,如果sizeof(a [0])== 1,这只能按预期工作.因此它适用于char,但wchar_t的含义不同. (3认同)
  • 考虑调试这样的代码:`printf("%c",[!! flag]"FT")`. (2认同)
  • 我很确定这应该是:`"FT"[!! flag]` - 如果你习惯将C字符串作为aarrays和booleans作为整数处理,那实际上并不是那么糟糕.它不像使用设计糟糕的运算符重载的C++代码那么糟糕. (2认同)
  • 这是**代码混淆**的完美之处.我们现在改变所有数组引用.;)我可以看到一堆困惑的面孔盯着这些...... (2认同)

Dip*_*ick 1293

在JavaScript中:

 '5' + 3 gives '53'
Run Code Online (Sandbox Code Playgroud)

 '5' - 3 gives 2
Run Code Online (Sandbox Code Playgroud)

  • +对于concat不是问题.打字很弱. (416认同)
  • @FogleBird这两个都不是问题所在.它只是两者的**组合**,具有不一致的强制规则. (270认同)
  • 字符串连接的`+`非常糟糕 (112认同)
  • 我记得当我第一次开始使用javascript时使用这种技术在字符串中添加数字:"111" - "222"给出333而"111"+"222"给出"111222". (81认同)
  • 所以基本上,当涉及到一个字符串时,+是concat.为什么他们不能像'123456'那样编码 - 456 ='123'?那会很有趣. (70认同)
  • 所以...在JavaScript中,'5'是27.5,3是25.5,对吧?:P (27认同)
  • 这很奇怪,但它确实有意义.您尝试向字符串添加数字,因此它与连接一起使用.在第二个中,您不能从字符串中减去一个数字,因此它只是将字符串转换为数字. (16认同)
  • "foo"+ +"bar"=>"fooNaN" (13认同)
  • 既不是`+`也不是弱打字就是问题.不了解语言语义的程序员就是问题所在.我的意思是:如果你认为从一个字符串中减去一个int形式是一个好主意,这都是你自己的错.如果你甚至不知道你的变量属于哪种类型 - 那就更糟了. (12认同)
  • +连接不是问题,Python的实现效果很好.它只是拒绝在没有转换的情况下添加int和str.在这种情况下,Javascript应该抛出异常. (9认同)
  • 这是Perl使用完全不同的运算符进行加法(+)和连接(.)的原因之一. (3认同)
  • @Jimmie Lin这会是一个决定吗? (3认同)
  • 如果你考虑串联实际意味着什么,那就很有意义了.当您连接"abc"和"def"时,您将"def"添加到"abc"的末尾.它不是数学上的补充,但逻辑上它是相似的.当然,这并不意味着使用+进行连接是个好主意. (3认同)
  • @Eric:我对concat的`+`没有问题.这只是一个象征.(这是我不喜欢的混合类型的行为方式).但是我发现字符串连接与数学加法的操作完全不同,首先是它不是可交换的. (3认同)
  • 我没有看到这种感觉.我的计算机科学理论课程或书籍都没有使用"+"来表示连接.无论如何,那是从哪里来的? (2认同)
  • 这正是我讨厌隐式字符串 - >数字转换以及允许它的任何语言的原因.同样,VB.Net也允许这样做 (2认同)
  • @Tom Hawtin - 强调:运算符*在数学中可能是非交换的.例如,在矩阵乘法中,A*B可能是可能的,而B*A是不可能的.我想不出+的任何例子,但我很确定会有. (2认同)
  • @SF:`alert('a'+ 2 + 3-5 + 7)`.你需要遇到一些更聪明的语言律师. (2认同)
  • 弱键入几乎不是问题,因为JavaScript不是弱类型.它是强类型的:根据语言定义,永远不会有任何疑问.它碰巧是动态类型的,但这并不会使它变弱.恰恰相反的是C,它是弱静态类型的:类型可以在编译时声明,但允许声明是错误的(由于转换),因此某些程序具有未定义的行为.问题(如果有的话)是隐式转换. (2认同)

Tam*_*ege 872

在JavaScript中,以下构造

return
{
    id : 1234,
    title : 'Tony the Pony'
};
Run Code Online (Sandbox Code Playgroud)

返回undefined是一个语法错误,因为在换行符后插入了偷偷的分号分号return.以下工作正如您所期望的那样:

return {
    id : 1234,
    title : 'Tony the Pony'
};
Run Code Online (Sandbox Code Playgroud)

更糟糕的是,这个也适用(至少在Chrome中):

return /*
*/{
    id : 1234,
    title : 'Tony the Pony'
};
Run Code Online (Sandbox Code Playgroud)

这是同一问题的变体,不会产生语法错误,只是默默地失败:

return
    2 + 2;
Run Code Online (Sandbox Code Playgroud)

  • 当你设计语言功能时,你总是遇到问题,假设你的用户大多是白痴. (230认同)
  • 分号插入是JavaScript中最邪恶的部分之一. (225认同)
  • 雅得喜欢这样:评出隐形代码! (144认同)
  • Nick Retallack:因为JavaScript的C类花括号和分号语法,所以新行很重要. (24认同)
  • 如果在使用JavaScript编程时不应该使用C风格,那么选择C风格语法的JavaScript语言设计者则相当不正常. (19认同)
  • 我实际上遇到了这个问题,我自己也是c#开发人员,我把支架放在了新的位置.花了我几个小时才意识到问题所在.即使我已经解决了这个问题,在我阅读你的答案之前我还不知道是什么问题! (8认同)
  • 为什么人们会为此投票?这将发生在具有重要换行符的任何语言中,例如Ruby和Python.为什么有人会知道新行是重要的? (6认同)
  • 我无法理解这是如何实现它的票数.它只能让在Javascript编程时尝试使用C风格的人感到惊讶.我希望人们放弃"首选"风格的概念,并将风格自然地用于他们编程的语言/项目. (6认同)
  • "特征"?我认为这个项目属于"最奇怪的语言*错误*". (5认同)
  • 严格的JavaScript语法不是样式偏好,它是良好的Web开发.编译C/C++/C#/ Java.JavaScript不是.每个空格都是另一个字节(两个用于Windows换行符)供用户下载.将其扩展到HTML/CSS,它就会增加.一些DotNetNuke页面有超过空白的20%页面权重(不包括图像); 他们使用4个空格的标签应该是.越来越多的移动用户以类似调制解调器的速度冲浪,促使谷歌将页面重量/下载时间作为今年搜索引擎排名的标准 - 现在是时候给出一个废话了. (5认同)
  • 这听起来像是一个文化问题,而不是一个语言问题.如果人们不认为他们应该使用分号,他们就不会感到困惑,发现他们的陈述也尽可能由换行符分隔.我永远不会用分号结束行(除了空的for循环,它期望一个语句),因为两个语句分隔符是多余的.也许会抱怨lisp中的括号或haskell或python中的缩进 - 这是语法的一部分,它就是设计的. (4认同)
  • 我希望人们不要再告诉其他人该怎么做了.你知道,我们都是成年人. (4认同)
  • @mcv:另外,我不同意你在*any*语言的行开头没有使用开括号.这是在大多数C风格语言中使用的完全有效的约定,并且(与标签结合)具有将每个开口支架与匹配的闭合支架对齐的优点.此外,一些大学计算机科学系要求它.但是,我同意,由于分号插入,特别是对JavaScript来说这是一个坏主意. (4认同)
  • 你可能想要观看Dough Crockford关于此的视频,第32分钟:http://goo.gl/zM5t (4认同)
  • @Matt:公平点,但是我相信现在,在生产环境中,你只会提供已经被JsMin和Closure Tools等工具预处理过的JavaScript,所以原始源代码并不真正类似于实际的JavaScript已经送达. (4认同)
  • 我现在正在学习Javascript,这对我来说是一个很大的WTF.分号插入?你在开玩笑吧!(+ 1 BTW) (3认同)
  • 我同意最后几条评论.你不应该在行的开头打开花括号(用任何语言),如果你知道行尾的分号是可选的,那么这种行为就变得非常明显了. (3认同)
  • Jason Orendorff:你说得对,它实际上会因意外的JSON而产生语法错误.我纠正了它并提供了一个实际上以静默方式返回undefined的示例.第三个例子确实不适用于Firefox,但它肯定适用于Chrome.这是一个众所周知的人工制品,不幸的是并非虚假. (2认同)
  • 这些都是JS的坏部分,为了避免这些,每个javascript开发人员都应该阅读Douglas Crockford的优点. (2认同)
  • 这不是一个错误,这是一个功能!真! (2认同)
  • @Nick Retallack,@ mcv:我认为令人困惑的是,只有*某些*换行符被视为分号,而其他*换行符则不会.例如`a = myFunc [newline](1)`与`a = myFunc;(1)`不同.在第一种情况下,a等于`myFunc(1)`返回的值,但在第二种情况下,a等于*function*`myFunc`. (2认同)

Cha*_*tni 795

JavaScript真值表:

''        ==   '0'           // false
0         ==   ''            // true
0         ==   '0'           // true
false     ==   'false'       // false
false     ==   '0'           // true
false     ==   undefined     // false
false     ==   null          // false
null      ==   undefined     // true
" \t\r\n" ==   0             // true
Run Code Online (Sandbox Code Playgroud)

资料来源:Doug Crockford

  • 好的东西Javascript有===运算符,然后. (237认同)
  • 困惑的人. (137认同)
  • 如果`=='具有`===`的含义,那就好了,然后有另一个运算符,比如`〜=`允许类型强制. (123认同)
  • 那么`=='在语言设计者眼中的用途是什么? (65认同)
  • @Otto实际上,由于我们正在寻找,他的例子表明==不对称.目前,我没有看到如何为二元关系指定可交换性. (18认同)
  • @Chris S:我认为应该按照人们的预期做大部分时间. (14认同)
  • 最糟糕的是==甚至不是等价关系,因为它不是自反性的:''=='0'是假的,但是0 ==''是真的. (9认同)
  • @Adam你的例子表明它不是可交换的.如果它不是自反的,则意味着0 == 0是错误的. (5认同)
  • 另一个Javascript怪异:255 == {valueOf:function(){return"0xFF"; }} //真的 (5认同)
  • 如果您认为javacsript是由委员会设计的,那么您需要返回并再次阅读历史记录. (5认同)
  • @Tom那是相关性的; http://en.wikipedia.org/wiki/Commutativity#Symmetry (4认同)
  • 从'==='运算符中区分'=='运算符(称之为"看起来像")(称之为"与...相同")仅在弱类型语言中有意义.例如,所有东西都有一个定义的字符串表示,这可以很方便,但是当第一次感觉到语法时会引起混淆. (3认同)
  • 这是由委员会设计的语言的基本问题,并且有机地逐渐增长.考虑英语. (3认同)
  • 这更像是真实表而不是真理表. (2认同)

Tho*_*ini 661

C和C++中的Trigraphs.

int main() {
   printf("LOL??!");
}
Run Code Online (Sandbox Code Playgroud)

这将打印LOL|,因为三字符??!被转换为|.

  • 这些让你使用"WTF操作符":( foo()!= ERROR)??!??!cerr <<"发生错误"<< endl; (360认同)
  • Trigraphs是惊人的,因为你可以肯定没有人会发现什么??!将意味着谷歌已经不知道名称. (235认同)
  • 快!告诉所有C/b /程序员! (71认同)
  • 当它们被引入时,三角形是必要的邪恶.有些平台只是没有包含该语言的某些关键字符,所以它既可以是"三字母",也可以是"你不能拥有C编译器句点结束语,所以请使用汇编程序".查看Stroustrup在"The C++ Programming Language"中的描述. (57认同)
  • 默认情况下,在GCC中禁用Trigraph. (56认同)
  • `| | |`用于在ascii游戏中绘制道路 (22认同)
  • 我曾经使用EBCDIC中的3270终端在IBM大型机上用C编程.C所需的一些字符(可能包括"|"字符)不在键盘上,并且在块模式终端上没有^ Q 7 C这样的功能.奇怪的是,有一个"|"(U + 00A6,"破碎的酒吧")字符.更奇怪的是,大多数现代美国PC键盘都在键上绘制了"|"字符,但PC将其变为"|" (11认同)
  • @Chris因为他们不是逃脱角色.该示例显示了在字符串中的使用,但是,得到这个,你可以在任何地方使用它们!像这样:`if(foo ??!??!bar)`而不是`if(foo || bar)`. (8认同)
  • @Adrian Pronk:当我长大的时候,我一直以为钥匙有一个破了吧很奇怪但是当我输入它时,酒吧很坚固.我把它作为其中一个"它是因为它是"的东西. (7认同)
  • dreamlax&Andreas:Trigraphs替换*由预处理器执行.见http://en.wikipedia.org/wiki/C_preprocessor (6认同)
  • 它不是编辑器的一个功能,而不是建立语言? (5认同)
  • @Tom Hawtin @voyager http://encyclopediadramatica.com/Rules_Of_The_Internet (5认同)
  • 三元组是否被预处理器改为等效字符? (3认同)
  • @Andreas:当然除了宏替换,对吧? (3认同)
  • @dreamlax - 这是因为PC键盘是在80年代设计用于DOS和(IBM/PC风格)ASCII.如果你启动一个控制台窗口,你会看到"断条"键仍然在那里输出一个"看起来很破旧的条形图".该栏是'破碎'所以它可以用`-`和`+`组成,以产生_very primitive_图形框.在Unicode中,我认为'破坏条'是在其他地方引入的(0xA6)兼容性,只是为了这样的图形仍然可以绘制. (3认同)
  • 什么是C/b /?我猜它与4chan没什么关系...... (3认同)

z *_* - 573

有趣的自动装箱和Java中的整数缓存:

Integer foo = 1000;
Integer bar = 1000;

foo <= bar; // true
foo >= bar; // true
foo == bar; // false

//However, if the values of foo and bar are between 127 and -128 (inclusive)
//the behaviour changes:

Integer foo = 42;
Integer bar = 42;

foo <= bar; // true
foo >= bar; // true
foo == bar; // true
Run Code Online (Sandbox Code Playgroud)

说明

快速浏览Java源代码将会出现以下内容:

/**
 * Returns a <tt>Integer</tt> instance representing the specified
 * <tt>int</tt> value.
 * If a new <tt>Integer</tt> instance is not required, this method
 * should generally be used in preference to the constructor
 * {@link #Integer(int)}, as this method is likely to yield
 * significantly better space and time performance by caching
 * frequently requested values.
 *
 * @param  i an <code>int</code> value.
 * @return a <tt>Integer</tt> instance representing <tt>i</tt>.
 * @since  1.5
 */
public static Integer valueOf(int i) {
    if (i >= -128 && i <= IntegerCache.high)
        return IntegerCache.cache[i + 128];
    else
        return new Integer(i);
}
Run Code Online (Sandbox Code Playgroud)

注意: 除非由属性IntegerCache.high设置,127否则默认为.

自动装箱会发生什么,除非明确创建foo = new Integer(42),否则foo和bar都会从缓存中检索相同的整数对象:例如,因此在比较引用相等时,它们将为true而不是false.比较Integer值的正确方法是使用.equals;

  • 很高兴我是一名C#程序员. (246认同)
  • @Will:C#有一些非常相似的陷阱.请参见http://blogs.msdn.com/jmstall/archive/2005/03/06/386064.aspx (87认同)
  • 花了几秒钟才知道为什么...... java必须为-128和128之间的值保留一个Integer实例池,否则它会分配一个新的Integer,对吗? (31认同)
  • 但请记住,如果指定new Integer(42),它将不会使用池中的实例,因此foo == bar将评估为false (18认同)
  • 如果可能的话,我总是使用int而不是Integers,但如果由于某种原因我不得不使用Integers,我应该使用.equals()而不是==吗? (10认同)
  • 我发现JAVA的程序员决定使用一个名为`IntegerCache.high`的可修改值,但前面只有1行,他们认为最好硬编码128(而不是使用IntegerCache.high + 1)更有意思. (10认同)
  • @monokrome:那个`128`用于重新定义数组,因此-128的汇集实例位于索引0,索引1处为-127,索引128处为0,依此类推.编写`IntegerCache.high + 1`将是一个*bug*. (6认同)
  • 最糟糕的是,我对这个功能的主要抱怨是,如果你从原语重构到整数,并且你的测试没有明确地尝试超出缓存范围的值,你将会出现一系列只出现的错误在生产中.不酷. (6认同)
  • 最重要的是,你可以使用反射使42等于你想要的任何东西! (5认同)
  • @spookylukey:最大的区别在于,在C#中你不需要一直打包整数,而在Java中你必须在开始使用泛型时就这么做,这很多次. (5认同)
  • 奇怪的功能,雅,问题,不,任何人比较对象与这些运算符有更多的担心而不是不一致的结果. (5认同)
  • 更令人费解的是,Java能够通过使1000更大和更小本身来打破数学定律! (4认同)
  • 有人可以解释为什么你只为一个整数子集创建一个整数池!? (3认同)
  • @all - 是auto(un)boxing是Java中最蠢的东西之一 - 在Java1.5中引入,因为人们仍然没有克服对原语的迷恋.@mono - 因为偏移量基于低值.如果有的话,他们需要一个新的IC.low变量. (3认同)
  • @Will:很高兴我使用Python ;-) (3认同)
  • 你在Java中使用'equals'. (3认同)
  • @MatrixFrog:是的,它们是对象. (2认同)
  • @ graham.reeds&johnc,想法是通过缓存最常用的整数来节省一点内存,而不是让几百万个包含值0的Integer对象,例如(0可能是最常用的,例如默认值)值). (2认同)
  • 这是过早优化的结果. (2认同)

lor*_*zog 373

引用Neil Fraser(看看那页的末尾),

try {
    return true;
} finally {
    return false;
}
Run Code Online (Sandbox Code Playgroud)

(在Java中,但在JavaScript和Python中的行为显然是相同的).结果留给读者练习.

编辑:只要我们在这个问题上,也要考虑这个问题:

try {
    throw new AssertionError();
} finally {
    return false;
}
Run Code Online (Sandbox Code Playgroud)

  • 值得庆幸的是,C#不允许这种疯狂......"控制不能离开最终条款的主体." (153认同)
  • 返回,假,是吗?它可能看起来像一个WTF(可能它是一个),但我遵守规则:最终总是赢,除非你之前崩溃机器. (64认同)
  • +1.出于某种原因,我觉得这很有趣,不能停止咯咯地笑. (42认同)
  • 公平地说,我责怪TDWTF很好的解释是为了记住,除非你猛拉电源线,否则最终总能获胜:http://thedailywtf.com/Articles/My-Tales.aspx (28认同)
  • 在这种情况下,我不确定代码应该返回什么.但我绝对相信你不能把`return`放在`finally`子句中. (22认同)
  • 即使你不能在`finally`中返回,下面的代码会做什么:`bool x = true; 试试{return x; } finally {x = false; }` (11认同)
  • @Chris刚刚在LINQPad中测试了它(对于C#),它返回true.另一方面,如果您将代码更改为`TestClass x = new TestClass(); x.Value = true; 试试{return x; } finally {x.Value = false; 其中TestClass是一个引用类,那么在控制返回调用方法之前,Value属性将被设置为false.因此,当命中返回时,似乎会将值复制到堆栈中,但仍会调用finally块(正如您所期望的那样). (6认同)
  • 请记住,"终于"完全符合它的说法. (6认同)
  • 这里的直观行为是fork(),控制分支到两个平行的时间轴. (5认同)
  • 这不是WTF.它是合乎逻辑的,因为最终,它将始终执行它的代码,因此它会覆盖所有内容,这就是它的方式. (4认同)
  • 控制不能在C#中留下finally子句的主体,这是不正确的.请参见8.10节:"如果在执行finally块期间抛出异常,并且未在同一个finally块中捕获,则异常将传播到下一个封闭的try语句.如果另一个异常正在传播,那么异常丢失." (静态检查"返回"只是一种特殊情况.)Java,Common Lisp,Python等.人.一切都是这样的. (3认同)
  • C++通过使用RAII而不是最终来避免这个问题. (3认同)
  • +10如果我在代码中使用了最终的回报,我正盯着它,大吃一惊并且有一个赛车头脑.顺便说一句,我立即将我的IDE中的"return inside finally block"警告更改为错误. (2认同)
  • 这太棒了.简单而辉煌 (2认同)

lke*_*ler 325

APL(除了ALL之外),能够在一行中编写任何程序.

例如康威在APL中的生命游戏:

替代文字http://catpad.net/michael/APLLife.gif

如果那条线不是WTF,那么什么都没有!

这是一个视频

  • 在科幻动作片中看APL会很棒.我可以想象有人坐在一个三色的终端嘀咕着"重塑敌人的导弹矢量......转置... pi时间对数...升级 - 然后执行!" 然后是爆炸和欢呼. (93认同)
  • @Erik:在编写完全与您想要的代码相关的代码中找到了快乐,而不是如何到达那里.将您的代码表达为单个表达式.这就像最终的完美武士刀剪裁.当然,在真正的战斗中,我宁愿拿枪. (45认同)
  • 看起来像希腊人的语言. (24认同)
  • 我喜欢APL.啊,花了整整一个下午写下半行代码的乐趣!当我拿到一个可以编程显示字母的键盘时,我要做的第一件事就是再次使用APL重新认识自己. (19认同)
  • @Daniel:你花了整整一个下午写一行代码......整整一周来*读*一行代码.;-) (7认同)
  • 哇,为什么不是代码高尔夫球手呢? (5认同)
  • @Daniel - 为什么?! (4认同)
  • 是的,但如果你的生产力按每天的代码行评定,这将使你看起来像一个可怕的程序员! (4认同)
  • @jay:生产率按代码行评定,与生产率在飞机设计中按重量评定相同! (4认同)

jos*_*efx 322

的奇怪的事情C++模板可用于,通过最好的证明"多维模拟字面",其使用模板来计算的"拉伸"的形状的区域.以下代码是3x3矩形的有效C++

#include"analogliterals.hpp"
using namespace analog_literals::symbols;

          unsigned int c = ( o-----o
                             |     !
                             !     !
                             !     !
                             o-----o ).area;
Run Code Online (Sandbox Code Playgroud)

或者,3D立方体的另一个例子:

  assert( ( o-------------o
            |L             \
            | L             \
            |  L             \
            |   o-------------o
            |   !             !
            !   !             !
            o   |             !
             L  |             !
              L |             !
               L|             !
                o-------------o ).volume == ( o-------------o
                                              |             !
                                              !             !
                                              !             !
                                              o-------------o ).area * int(I-------------I) );
Run Code Online (Sandbox Code Playgroud)

  • 真正的WTF将是其中一个格式错误的编译器错误. (85认同)
  • 虽然Eelis的模拟文字很棒,但它们是一种奇怪的语言*功能*,还是只是一种奇怪的方式*使用*功能? (18认同)
  • 当有一个版本的AnalogLiterals支持在Eclipse中围绕X,Y和Z轴旋转文字时,再次唤醒我...现在这会给"视觉编程"一个新的真正含义. (6认同)
  • 排序很重要,因为模板创造性地使用了运算符重载.(不要使用实际代码执行此操作,滥用运算符会使代码难以阅读) (4认同)
  • o和L的排序和|和s的关系? (2认同)

Chr*_*s S 292

Perl的许多内置变量:

  • $#- 不是评论!
  • $0,$$$?- 就像shell变量一样
  • $?,$&$'- 奇怪的匹配变量
  • $"$,- list-和output-field-separator的奇怪变量
  • $!- 像errno一个数字,但strerror(errno)作为一个字符串
  • $_- 隐形变量,总是习惯从来没见过
  • $#_ - 最后一个子程序参数的索引号...也许
  • @_ - 当前函数的(非)名称......也许
  • $@ - 最后提出的异常
  • %:: - 符号表
  • $:,$^,$~,$-,和$=-是与输出格式
  • $.$%- 输入行号,输出页码
  • $/$\- 输入和输出记录分隔符
  • $| - 输出缓冲控制器
  • $[- 将阵列基础从0基础更改为基于1基于42基础:WHEEE!
  • $}- 什么都没有,奇怪的是!
  • $<,$>,$(,$)-真实和有效的UID和GID
  • @ISA - 当前包的直接超类的名称
  • $^T - epoch秒中的脚本启动时间
  • $^O - 当前的操作系统名称
  • $^V - 这是什么版本的Perl

那些来自的地方还有很多.阅读完整的列表在这里.

  • `$ [`变量是他们中最邪恶的. (83认同)
  • 如果Perl 6是我可以编码的东西而不必每五秒钟检查一次'perldoc perlvar`,那肯定会很感激.(虽然我承认有一半时间我会检查它"我知道有一个特殊的变量可以为我做这个,我只是不记得哪一个......"= P) (24认同)
  • `use English;`的问题在于它会影响RegExp的性能.我不是这样做的.http://perldoc.perl.org/English.html#PERFORMANCE (17认同)
  • @Dave:由于您链接的页面中的-no_match_vars选项,这不是问题.@Brad:$ [太邪恶了.背后的意图是邪恶的,是的,但它甚至都不起作用!@Artem:来自perlvar"以数字,控制字符或标点符号开头的Perl标识符不受包声明的影响,并且总是被强制包在main中;它们也免于严格的'vars'错误." 这意味着即使在狭窄的情况下,@ $也会被创建并分配给它而没有错误.啊! (13认同)
  • @Brian:当官方文档本身指出Perl解释器*启发式猜测*字符序列意味着什么的情况时,您如何建议学习语法?例如在`/ $ foo [bar] /`中,`[bar]`部分是字符类或数组`@ foo`的下标?Grep perldata的可怕答案. (4认同)
  • $ _是我最喜欢的变量.必须在php中编写foreach($ a as $ v)会让我的头发受伤. (3认同)

Dan*_*yer 289

PHP在字符串中处理数值.有关完整详细信息,请参阅此前一个不同问题的答案,但简而言之:

"01a4" != "001a4"
Run Code Online (Sandbox Code Playgroud)

如果您有两个包含不同字符数的字符串,则它们不能被视为相等.前导零是重要的,因为这些是字符串而不是数字.

"01e4" == "001e4"
Run Code Online (Sandbox Code Playgroud)

PHP不喜欢字符串.它正在寻找任何可以找到将你的价值观视为数字的借口.稍微更改这些字符串中的十六进制字符,突然PHP决定这些字符串不再是字符串,它们是科学记数法中的数字(PHP并不关心您使用引号)并且它们是等效的,因为数字会忽略前导零.为了强调这一点,您会发现PHP也会评估"01e4" == "10000"为true,因为这些是具有等效值的数字.这是记录在案的行为,它不是很明智.

  • 只需使用===和!==.除非需要进行松散的类型比较,否则应该使用哪种方法. (56认同)
  • 我一直都知道PHP是一种罪恶.到目前为止,我没有意识到这是一个不可饶恕的罪:D (43认同)
  • 弱打字再次打击! (18认同)
  • @Dykam,如果你按照更全面的答案的链接,你会看到我已经解决了使用===运算符的问题. (14认同)
  • 技术人员应该在任何编程书籍或教程中使用===.补充说明:在一个编写得很糟糕的PHP应用程序中,我能够提供任何被解析为相同数字的密码. (2认同)

Bri*_*ing 282

JavaScript八进制转换'功能'是一个很好的了解:

parseInt('06') // 6
parseInt('07') // 7
parseInt('08') // 0
parseInt('09') // 0
parseInt('10') // 10
Run Code Online (Sandbox Code Playgroud)

更多细节在这里.

  • 陷入了一个错误,除了8和9之外所有数字都有效!疯了!!! 谢谢Brian! (60认同)
  • 这就是为什么parseInt采用(可选的)额外参数:). (48认同)
  • ...和parseInt('010') - > 8只是为了让你迷惑. (22认同)
  • @Yada你不是指八进制吗?十六进制是0x. (10认同)
  • 前导0表示八进制数.由于8不是有效的八进制数字,因此结果必须为0. (10认同)
  • 解析整数时,应始终传递base参数.parseInt('08')== 0而parseInt('08',10)== 8 (6认同)
  • 在ES5中更改:"函数parseInt的规范不再允许实现将以0字符开头的字符串视为八进制值." (2认同)

MZB*_*MZB 282

让我们对试图取消保留字的所有语言(例如PL/I)进行投票.

还有什么地方可以合法地写下这样有趣的表达:

IF IF THEN THEN = ELSE ELSE ELSE = THEN
Run Code Online (Sandbox Code Playgroud)

(IF,THEN,ELSE是变量名)

要么

IF IF THEN THEN ELSE ELSE
Run Code Online (Sandbox Code Playgroud)

(IF是一个变量,THENELSE分别表示子程序)

  • @RoadieRich一群水牛没有明确地来自布法罗,他们只是一个不起眼的水牛. (28认同)
  • 詹姆斯过去的约翰曾经对老师有过更好的影响. (18认同)
  • 也许未来的时间计划需要它.如果那么=现在&&在哪里=在这里然后=那么现在=在其他地方 (9认同)
  • 前几天我在Ben和jerrys冰淇淋工厂外面看到了一些标牌制造商.我批评他们的工作,我告诉他们,本和和之间没有足够的空间和jerrys. (4认同)

Fru*_*nsi 213

Duff的装置在C!

在C中,可以使用switch语句交换do/while.这是使用此方法的memcpy的示例:

void duff_memcpy( char* to, char* from, size_t count ) {
    size_t n = (count+7)/8;
    switch( count%8 ) {
    case 0: do{ *to++ = *from++;
    case 7:     *to++ = *from++;
    case 6:     *to++ = *from++;
    case 5:     *to++ = *from++;
    case 4:     *to++ = *from++;
    case 3:     *to++ = *from++;
    case 2:     *to++ = *from++;
    case 1:     *to++ = *from++;
            }while(--n>0);
    }
}
Run Code Online (Sandbox Code Playgroud)

  • @frunsi:Duff自己,发表它,声称这样的话:"这肯定在讨论中提供了一个论证是否应该默认情况下切换,但我不确定这个论点是赞成还是反对." (37认同)
  • @frunsi:"Duff的设备可能是开关语句默认没有中断的一个很好的理由" - 总是将常见情况设为默认值.我不会说这是常见的情况.. (16认同)
  • 请记住,Duff的设备通常会生成WORSE代码而不是现代编译器的正常循环语句,后者知道如何(更好)循环展开而不是手动执行. (14认同)
  • Duff的设备可能是开关语句默认没有中断的一个很好的理由;-)然而,我还没有看到隔行开关和循环的任何其他好用 - 但可能有一个.哦等等,是的,还有另一种用途:协程和protothreads. (9认同)
  • @mcv可能最简单,如果你尝试将其作为汇编代码读取,即最后的`while`是一个(有条件的)`JMP`回到`do`,这解释了为什么你可以跳过`do`并仍然结束在循环中. (6认同)
  • 此技术还可用于在C中实现无堆栈线程,如Contiki操作系统:http://www.sics.se/~adam/pt/ (2认同)

Ric*_*ton 204

Algol按名称传递(使用C语法说明):

int a[3] = { 1, 2, 3 };
int i = 1;

void f(int j)
{
    int k;
    k = j;  // k = 2
    i = 0;
    k = j;  // k = 1 (!?!)    
}

int main()
{
    f(a[i]);
}
Run Code Online (Sandbox Code Playgroud)

  • 这是最终的"参考传递". (90认同)
  • 如果你考虑一下,它实际上会产生某种扭曲的感觉 (33认同)
  • 所以这就像`... template <typename T> struct by_name {virtual operator T&()= 0; }; void f(by_name <int> j){...} int main(){f(struct:by_name <int> {operator int&(){return a [i];}}); }`? (10认同)
  • 但是在Scala中有可能(`def f(j:=> int)`) (3认同)
  • 它实际上非常简单:你生成一小段代码(通常称为"thunk",因此我的双关语),它计算表达式产生的地址,在本例中为a [i].指向此函数的指针将传递给被调用函数,然后在每次访问参数时使用它来计算当前地址. (2认同)
  • 我刚刚去世并下地狱. (2认同)
  • 这最初是为集成和衍生物之类的东西完成的.这确实是穷人的关闭.无论你传入的表达有多复杂,每次它出现在函数的文本中时都会重新评估.想想副作用的乐趣!而且,如果我没记错的话,那也是传递参数的默认方法.据我所知,在Algol 68中它被称为_proceduring_并且不再是默认值. (2认同)

MAK*_*MAK 189

在Python中:

>>> x=5
>>> 1<x<10
True
>>> 1<x<3
False
Run Code Online (Sandbox Code Playgroud)

不是WTF,而是一个有用的功能.

  • 我希望所有其他语言都有此功能 (176认同)
  • @Khelben:不,在这个例子中,`funct_a`将被调用两次.在`b> funct_a(5)> c`中,它只会被调用一次,而不是`b> funct_a(5)和funct_a(5)> c`. (57认同)
  • 与几乎所有酷炫的Python功能一样,看起来像Guido只是ALGOL-lzed一个很酷的Lisp功能的语法.:-) (32认同)
  • 此外,它只评估一次,所以`(funct_a(5)+5> b> funct_a(5))`只调用`funct_a(5)`一次.这是一个很棒的功能! (18认同)
  • 杰弗里,这是一个特色,而且(10> 5> 1)!=((10> 5)> 1)`在Python中. (4认同)
  • 在学习了很多fortran和C之前,我精通Python,所以这导致了一段C代码中的微妙WTF.那*不容易发现. (3认同)
  • 实际上Khelben说的是*令人惊讶的,恕我直言. (3认同)
  • 但这个功能有什么奇怪的吗?对我来说,这是合乎逻辑的. (3认同)
  • @Baffe_Boyois @MatrixFog对不起,伙计们,你说得对!我想在我写这篇文章的那天,我喝醉了.正确的答案是Baffe Boyois所说的...... (3认同)
  • 这不是WTF.它节省了打字(和评估); 我认为它与Perl 5.10的'defined-or'运算符有关. (2认同)
  • 更好的是lisp版本:(<0 1 2 3 4)=> true <function实际测试所有参数是否按升序排列. (2认同)
  • 该死的...更糟糕的是,它在C语言(以及它的所有后代)中是完全正确的语法,但在那里产生完全不正确的结果.`((bool)(1 <a))<3` (2认同)

Cha*_*tni 189

在Java中:

int[] numbers() {
  return null;
}
Run Code Online (Sandbox Code Playgroud)

可以写成:

int numbers() [] {
  return null;
}
Run Code Online (Sandbox Code Playgroud)

  • 我讨厌这样说,但WTF是C型系统的一致扩展.如果允许C函数返回数组,那就是它的样子.更好的是一致性违规,使其更具可读性.很像"const char*var"vs"char const*var". (29认同)
  • 哇!我希望在设计阵列语法时我能成为墙上的苍蝇! (23认同)
  • @Adam - 当你认为变量声明同样允许"int stuff []"和"int [] stuff"时,它实际上是有意义的.他们只是让相同的规则适用于方法声明. (15认同)
  • 毕竟,`numbers()[2]`是一个法律声明. (3认同)
  • @lImbus:实际上,`const T*`和`T const*`是等价的,它是`T*const`,它反映了指针.另外,我讨厌没有字体. (2认同)

Jef*_*ter 184

INTERCAL可能是最奇怪的语言功能的最佳纲要.我个人最喜欢的是COMEFROM声明,它几乎与GOTO相反.

COMEFROM与GOTO大致相反,因为它可以将执行状态从代码中的任意点转换为COMEFROM语句.发生状态转移的代码中的点通常作为COMEFROM的参数给出.传输是在指定传输点的指令之前还是之后发生,取决于所使用的语言.根据所使用的语言,引用相同出发点的多个COMEFROM可能无效,是非确定性的,以某种定义的优先级执行,或者甚至引起并行或以其他方式并发执行,如在线程间隔中所见."COMEFROM x"语句的一个简单示例是标签x(它不需要物理上位于其对应的COMEFROM附近的任何位置),充当"陷阱门".当代码执行到达标签时,控件将传递给COMEFROM之后的语句.这样做的主要目的是使调试(并理解程序的控制流程)非常困难,因为标签附近没有迹象表明控件会神秘地跳转到程序的另一个点.

  • 好吧,但INTERCAL应该很有趣 - 这并不是一个令人惊讶的"陷阱".如果你不经常使用`PLEASE`修饰符,INTERCAL编译器实际上可以拒绝编译程序! (114认同)
  • 相当邪恶 - 将标签变成GOTO.听起来像黑客乞求的语言功能...... (16认同)
  • 听起来像AOP :) (10认同)
  • 令我惊讶的是,在"商业TI世界"中的系统需求分析中,COMEFROM实际上用于描述用例的文本文件中.(严重的是:一些分析师推迟了公司广泛迁移到OpenOffice而不是MS的Office,因为前者无法正确引用链接中所需粒度的"来自") (6认同)
  • Groo:情况更糟.过于频繁地使用PLEASE并且它拒绝编译你的程序,因为你正在卑躬屈膝(C-INTERCAL需要33%到66%的语句才能拥有PLEASE修饰符). (5认同)
  • @alex:这只是在Threaded-INTERCAL实现中.它不是INTERCAL规范的一部分.(当我说"INTERCAL spec"时,我忍不住笑了) (2认同)
  • COMEFROM声明被认为是有害的 (2认同)
  • 但真正的美妙之处在于你可以拥有来自同一行的*多个*语句......是的,intercal有多线程! (2认同)
  • 它只是我,还是这听起来真的像.NET中的普通事件? (2认同)

Ric*_*ton 160

不是一个语言功能,而是一个实现缺陷:一些早期的Fortran编译器通过使用常量池实现了常量.所有参数均通过引用传递.如果你调用了一个函数,例如

f(1)
Run Code Online (Sandbox Code Playgroud)

编译器会将常量池中常量1的地址传递给函数.如果为函数中的参数指定了值,则可以在程序中全局更改值(在本例中为值1).引起一些头部刮伤.

  • 哦.然后`2 + 2`*可以*等于'5'(当然,对于非常大的'2`值!). (124认同)
  • @earlz:我怀疑它会成为一个整数值,无论是什么位模式.另一方面,你可以用这种方式设置5到4(所以`2 + 2`对于'5`的小值来说等于'5`). (36认同)
  • 对不起,Alok,但这是我们谈论的早期FORTRAN."2 + 2 = 5"是不正确的; 这将是一个语法错误.什么是真的是'2 + 2 .EQ.5`. (18认同)
  • 嗯,2的值是"2 + 2"=="5"?我不知道任何整数值2可以承认这是真的. (12认同)
  • 在Haskell中,以下代码段评估为5:"让2 + 2 = 5 + 2 + 2":) (3认同)
  • 也许我们可以将报价更改为"2 + 2 = 5,非常小的值为5".http://www.thinkgeek.com/tshirts-apparel/unisex/generic/60f5/ (2认同)

Dmi*_*try 153

不知道它是否可以被认为是一种语言特性,但是,在C++中,几乎所有与模板相关的编译器错误都会为全世界的许多C++程序员每天提供相当数量的WTF :)

  • 即使没有错误,也可以尝试使用分析器查找哪些函数花费的时间最长.哦,看,它是`std :: vector <std :: pair <int,std :: complex>,std :: allocator <std :: pair <int,std :: complex >>> :: vector <std :: vector <std :: pair <int,std :: complex>,std :: allocator <std :: pair <int,std :: complex >>> :: iterator>(std :: vector <std :: pair <int, std :: complex>,std :: allocator <std :: pair <int,std :: complex >>> :: iterator,std :: vector <std :: pair <int,std :: complex>,std :: allocator <std :: pair <int,std :: complex >>> :: iterator,std :: allocator <std :: pair <int,std :: complex >>) (111认同)
  • 哦,现在来吧.未定义引用`std :: basic_ostream <char,std :: char_traits <char >>&std :: operator << std :: char_traits <char >>(std :: basic_ostream <char,std :: char_traits <char> >&,char const*)'完全可读! (43认同)
  • 没关系,大多数与模板相关的代码已经在全世界创造了大量的WTF. (15认同)
  • 我认为这适合:在http://www.bdsoft.com/tools/stlfilt.html上查看STLFilt以使输出可读. (12认同)
  • 我曾经有一个模板相关的编译器错误是五行,最短​​的是17000个字符(经典的'不匹配x'错误,在一个深度模板化的程序中).那是WTF,而不是首先出现的功能,模板很精彩. (10认同)
  • 模板错误信息充满了意义,对于一些**奇怪的**原因有些人无法理解6整页的纯粹含义...... (3认同)

Vic*_*aci 150

C的许多名称空间:

typedef int i;

void foo()
{
    struct i {i i;} i;
    i: i.i = 3;
    printf( "%i\n", i.i);
}
Run Code Online (Sandbox Code Playgroud)

或者使用字符:

typedef char c;

void foo()
{
    struct c {c c;} c;
    c: c.c = 'c';
    printf( "%c\n", c.c);
}
Run Code Online (Sandbox Code Playgroud)

  • 枚举和结构的+1标记标识符是C imho中最令人困惑的部分.很少有人理解为什么键入一个指向结构的指针的习惯看起来就像它那样. (13认同)
  • 它编译,因为我的每一个都有一个由于上下文明确的命名空间. (11认同)
  • @jae:当然,这是不可读的.但仍然毫不含糊. (3认同)

Bry*_*ley 149

我会说Python的整个空白是我最强大的WTF功能.确实,你或多或少习惯了一段时间后现代编辑人员可以轻松应对,但即使在过去一年大部分时间进行python开发之后,我仍然相信这是一个坏主意.我已经阅读了它背后的所有推理但老实说,它妨碍了我的工作效率.不是很多,但它仍然是马鞍下的毛刺.

编辑:根据评论判断,有些人似乎认为我不喜欢缩进我的代码.这是一个不正确的评估.无论语言是什么以及我是否被迫,我总是缩进我的代码.我不喜欢的是缩进定义了一行代码块.我更喜欢明确的分隔符.除了其他原因之外,我发现明确的分隔符可以更轻松地剪切和粘贴代码.

例如,如果我有一个块缩进4个空格并将其粘贴到缩进8个空格的块的末尾,我的编辑器(所有编辑器?)不知道粘贴的代码是属于8空间块还是外部块.OTOH,如果我有明确的分隔符,很明显代码属于哪个块以及它应该如何(重新)缩进 - 它通过智能地查找块分隔符来实现.

编辑2:一些提供评论的人似乎认为这是我讨厌的一个功能,或者我认为这使得python成为一种糟糕的语言.再次,不是真的.虽然我不喜欢这么多,但这不是重点.问题是关于最奇怪的语言特征,我认为这很奇怪,因为它是非常非常少(但> 0)种语言使用的东西.

  • 这是交易 - 使用任何其他语言,我可以突出显示一段代码并让任何编辑器正确缩进.但是因为空格按照定义是正确的缩进,所以你在Python中失去了这种能力.因此,移动代码或重构代码更加困难.而对于声称OP是"第一个声称它是一个问题的人"的人,我必须维持一段时间的python代码,因此我现在将使用任何语言而不是python. (83认同)
  • 如果它妨碍了你的工作效率,那么你的非python代码就不会非常易读...... (63认同)
  • +1如果我的编辑器(Emacs)无法根据不同的东西(如大括号/开头,结束/你自己命名)缩进我的代码,那么就不能同意了,这是非常愚蠢的.几乎任何你在"更大"的功能上进行的重构都可能是一次非常糟糕的体验. (53认同)
  • 我不介意Python中的空格.WTF是它没有一贯强制执行.你可以混合缩进级别和标签,只要它们与兄弟姐妹一致.因此第一个缩进级别可以是一个空格,第二个缩进级别可以是两个TAB,这不是语法错误. (38认同)
  • 在Python之前你使用了什么语言?你是如何与其他人合作而不是缩进那种语言?怎么可能在*any*语言中忍受非缩进代码?你是否在一个充满天才的房间工作,他们在源代码中不需要视觉提示? (27认同)
  • 他有没有说他根本不喜欢缩进?但是被迫以各种价格,并且不得不处理奇怪的空间与选项卡问题可能会很痛苦.(我希望我没有告诉垃圾,因为我从来没有真正做过Python) (9认同)
  • 让我直截了当地说:您经常重新排列代码块,以便重新调整它们的几次按键会降低您的工作效率. (9认同)
  • 哇,这是第一个反对Python重要空白的论据,对我来说很有意义.我遇到了"我已经移动了这段代码,现在必须手动修复缩进"问题很多次. (8认同)
  • 如果您正在使用Vim,请查找`] p`和`] P`命令,这有助于将代码粘贴到新位置,同时自动使用正确的缩进. (8认同)
  • 它确实以生产力的方式获得了!! 编辑器无法确定粘贴代码的缩进应该是什么,vi的"%"命令不再起作用,如果你在缩进中出错,则没有"{"或类似的可能突出显示这个错误的任何人在复杂的语句上阅读代码,这些语句超过一个屏幕,它与猪匹配块的末尾匹配'if','for'或者其他什么.仍然是为最优雅的编程语法付出的小代价. (6认同)
  • 你可以随时做:从__future__导入括号并使用大括号:) (6认同)
  • 缩进块是我最喜欢的Python(和Haskell的相应布局)之一.是的,它使复制粘贴不那么"高效",更有可能产生破坏的代码,但它使得编写代码的_read_更容易.是的,它迫使程序员手动布局他的代码.想想排版书籍(Python)与文本标记(类似C).顺便说一下,用意大利键盘布局进入大括号是一种痛苦......(我不会正常使用它,但是当我不得不这样做时,这是一种痛苦). (5认同)
  • 我想知道有多少人不知道许多编辑器的块缩进功能.即高亮显示一个文本块(几行)并按TAB键将整个块推入,然后按SHIFT-TAB将其移出.如果你知道它是"显而易见的",但在那之前重新调整是很多工作. (5认同)
  • @presario你不相信别人可以有不同于你自己的意见吗? (5认同)
  • 令我惊讶的是,有人说他们喜欢Python的缩进错误,因为它强制执行基于结构的精简缩进.好像,当他们用C语言或其他语言写作时,他们并不打算缩进他们的代码.我从来没有见过专业编写的C程序没有使用适当的缩进.这个Python的东西修复了现实世界中不存在的问题.在您看到格式错误的代码的地方,您的现代文本编辑器可以通过触摸按钮来美化它. (5认同)
  • @RCIX:理论上听起来不错.在实践中,人们仍然可以自由选择使用的缩进量,因此您仍然必须依赖于组内的标准.就在上个月,我不得不重新缩进由新团队成员签入的一堆代码,因此在这方面,Python实际上并不比任何其他语言更好或更差. (4认同)
  • @Khelben:总共4个空格?你确定吗?...与C++(或任何其他bracy语言)的区别在于*你*不需要纠正的事情.您可以要求编辑为您完成. (4认同)
  • @Bryan:看看文档,或尝试一下.Vim调整粘贴块的缩进,以使粘贴的第一行与光标所在的行对齐.``p`和`] P`之间的区别在于粘贴的文本是插入当前行的下方还是上方. (4认同)
  • 你是我见过的第一个人,即使在长时间使用它之后仍然是一个"问题". (3认同)
  • "如果python的定义具有空格的块的模式如此优越,为什么它实际上是过去或现在唯一的语言呢?" - >其他例子:boo(好吧,它基于python语法),Haskell. (3认同)
  • @ e-satisf,我实际上比python更喜欢ruby(并且可能比ruby更好)但在我的工作中我们使用python.我不明白你的评论.请记住,问题不是"你讨厌什么语言",而是什么是奇怪的,令人惊讶的,或者是WTF.我认为可以肯定地说,因为python是以这种方式使用whatspace的非常非常少量的语言之一,它符合"令人惊讶或奇怪"的定义.关于python还有很多其他的东西超过了这个功能.Python是一种很好的语言,但它使用的是空白是IMO,"奇怪,奇怪或者WTF". (3认同)
  • +1这是完全正确的.虽然我同意使用空格减少噪音并可能有助于提高可读性,但它让我头疼很多次.由于代码不仅仅是散文文本,我认为最好使用显式分隔符进行结构化. (3认同)
  • 另一件事是它意味着该语言的每个用户必须使用相同的格式,这是恕我直言的好事. (2认同)
  • 肯德尔:你的编辑不能为你做,因为它是语法的一部分.(我不确定它如何使重构变得更难;我在过去十年中使用的每个编辑器都变得很愚蠢 - 很容易进入/ dedent.)这就像一个Lisp程序员抱怨在C中你不能只突出一个块代码并让你的编辑器正确地利用它 - 大写是C语言的一部分,所以显然编辑器不能为你做.但这不是问题,因为我可以认识到大写字母在C中很重要,所以任何重构都必须*包含*,就像它在Python中缩进一样. (2认同)
  • 对我来说可怕的是有多少程序员发现复制/粘贴必不可少(以及编写丢弃函数的次数). (2认同)
  • @xcramps:复制/粘贴对于重构至关重要.当我将一段代码移出或移入函数或类定义时,我使用复制/粘贴.有时移动需要缩进级别的变化.根据我的经验,使用明确的块分隔符可以更容易. (2认同)
  • 复制和粘贴很有用,但不是必需的.剪切和粘贴对于重构至关重要.关于移动代码和编辑器的块 - 无论移动块的容易程度如何,在Python中我都要思考正确的位置是什么.在任何其他语言中,编辑器自动缩进是一种健全性检查 - 如果在重新格式化之后缩进看起来不对,我知道我有一个块分隔符错误.您无法在Python中执行此类检查,因为编辑器无法覆盖您的格式.我的所有代码格式都很好,因为我的编辑经常为我做这件事. (2认同)
  • +1这正是我在需要时使用Perl而不是Python的原因.如果你需要压痕迫使你,你太懒了. (2认同)

mik*_*iku 138

我对此有点挣扎:

1;
Run Code Online (Sandbox Code Playgroud)

在perl中,模块需要返回真实的东西.

  • 某些模块可能会根据运行时操作返回值.如果你总是返回true,你仍然不必对它没有创造力:http://returnvalues.useperl.at/ (29认同)
  • Mark Dominus写道,"我很少使用''Cogito ergo sum';"众所周知,在所有可能的宇宙中都是如此.这确保了最大的便携性." (24认同)
  • 如果我的Perl内存正确地为我服务,则从模块返回true表示模块已成功加载.返回错误值意味着出现了错误并阻止程序运行(如果没有捕获). (8认同)
  • 许多模块确实以giggles结尾:'false'; (2认同)

Bri*_*tow 135

我很惊讶没有人提到Visual Basic的7循环结构.

For i As Integer = 1 to 10 ... Next
While True ... End While
Do While True ... Loop
Do Until True ... Loop
Do ... Loop While True
Do ... Loop Until True
While True ... Wend
Run Code Online (Sandbox Code Playgroud)

因为坚持!在有条件的正面的方式太复杂!

  • !不是在VB中,它是"不".或者是吗?是的,不是不是!,但不是. (61认同)
  • 哇.当我想到它时,我会有点怀旧.我第一次使用VB时又回到了9岁.我来自瑞典,当时对英语不太熟练.现在,有一个名为"vänd"的瑞典语单词,基本上意味着"回头",发音类似于"wend".因此我觉得它很有意义...... :) (48认同)
  • 他们应该把它做成"`while`和`Whend`",因为有些人用无声的唇腭近似词发音"while".当然它排队更好,排队的代码很好. (47认同)
  • 你为什么这么做? (43认同)
  • 是的,"Wend"是一个英语单词,意思是去某个课程或方式(http://www.google.com/search?q=define%3A+wend).我不确定这有助于帮助还是伤害. (7认同)
  • @mmyers:VB中的"wend"和英语中的"wend"有两个非常不同的定义.VB的"wend"表示"重复"或"再次",但英语中的"wend"根本不包括任何重复.如果有的话,我认为`Wend`应该是`goto`的替代品.`On Error Wend FixIt` (3认同)
  • 我没有看到问题. (3认同)
  • 我也认为Wend是While End的简称 (3认同)
  • 蜿蜒?我喜欢bash等人的fi(endif)和esac(endcase). (2认同)
  • @dreamlax:Bash使用`case`和`esac` :).无论如何,我一直认为`Wend`应该是`Wendy`. (2认同)
  • VB还有一个迭代循环的循环`For Each foo In foos ... Next foo` (2认同)
  • @dreamlax:+1为"清音舌侧近似" (2认同)
  • 他们把它添加到VB? (2认同)

Alo*_*hal 134

对于那些不知道的人来说,bc是一种"任意精确计算器语言",我经常使用它进行快速计算,特别是当涉及的数字很大时($提示):

$ bc -lq
12^345
20774466823273785598434446955827049735727869127052322369317059031795\
19704325276892191015329301807037794598378537132233994613616420526484\
93077727371807711237016056649272805971389591721704273857856298577322\
13812114239610682963085721433938547031679267799296826048444696211521\
30457090778409728703018428147734622401526422774317612081074841839507\
864189781700150115308454681772032
Run Code Online (Sandbox Code Playgroud)

bc很长一段时间以来一直是标准的Unix命令.

现在为"WTF功能".这来自man bc(强调我的):

退出:当读取quit语句时,无论在哪里找到退出语句,都会终止bc处理器. 例如,"if(0 == 1)quit"将导致bc终止.

halt:halt语句(扩展名)是一个执行语句,它导致bc处理器仅在执行时退出. 例如,"if(0 == 1)halt"不会导致bc终止,因为没有执行暂停.

  • 我使用Haskell来做这些事情. (41认同)
  • 谷歌计算器? (8认同)
  • 我自己开始使用Python,如果你在线,谷歌计算器很不错.但是之前我常常使用`bc`,并且想在我的帖子中写一下`bc`,因为man页面引用了很多引号. (7认同)
  • @Brian,那么你会喜欢:`echo'[q] sa [ln0 = aln256%Pln256/snlbx] sb3135071790101768542287578439snlbxq'| dc`(虽然你可能已经知道了). (6认同)
  • 我使用irb(Ruby交互式shell).但是在当天,我总是达到直流 - 就像bc一样,但是使用反向抛光.Geektastic! (2认同)

Did*_*set 134

我总是想知道为什么最简单的程序是:

class HelloWorldApp {
    public static void main(String[] args) {
        System.out.println("Hello World!");
    }
}
Run Code Online (Sandbox Code Playgroud)

而它可能是:

print "Hello World!"
Run Code Online (Sandbox Code Playgroud)

也许这首先是吓唬计算机科学的学生......

  • 我喜欢那些认为OOP意味着一切都应该是一个对象的人. (68认同)
  • @Loadmaster:暗示"所有代码都属于一个类"或"所有代码都属于一个函数"是不必要的约束 (36认同)
  • 在某些语言中,"Hello World!" 是一个有效的计划. (34认同)
  • @SoMoS:在大多数动态语言中,如Python,Ruby或Perl,打印"Hello World!" 或者一些微小的变化(例如,放置而不是打印)是一个有效和完整的程序. (31认同)
  • 仅仅因为一种语言强制使用对象,并不意味着它被用于正确的面向对象编程.完全可以在Java或C#中进行程序化编程.这就是静态方法的用途. (19认同)
  • 嘿,在APL"Hello World!"中,该程序将如何发展.必须比这个"Java"更容易使用! (9认同)
  • @Jimmy:这就是OOP语言的严格运作方式. (5认同)
  • 这是一块垃圾..不,OOP不是你的平均结构化/非结构化编程类型. (5认同)
  • 我看到更糟......就像Win32 C版"Hello World":P http://www.paulgriffiths.net/program/c/srcs/winhellosrc.html (5认同)
  • BlueRaja:答案中的代码不是严格的OOP.要严格地说是OO,你需要实例化一个对象并调用一个方法来让它做某事. (4认同)
  • @BlueRaja:在.NET中,所有代码都必须在类/结构方法中.这并不能阻止boo(一种.NET语言)"打印"Hello World!"`作为它的hello world程序. (4认同)
  • 为什么不只是`h`?它在Jon Skeet的Hello World语言中有效.:) (3认同)
  • 如果您在任何时间使用Java都有意义. (2认同)

The*_*heo 132

JavaScript是面向对象的,对吧?因此,对文字字符串和数字运行方法应该有效.喜欢"hello".toUpperCase()3.toString().原来第二个是语法错误,为什么?因为解析器期望一个点后面跟一个数字作为浮点文字.那不是WTF,WTF是你只需要添加另一个点来使其工作:

3..toString()
Run Code Online (Sandbox Code Playgroud)

原因是文字3.被解释为3.0,并且3.0.toString()工作正常.

  • 你可以做(​​3).toString() (49认同)
  • `3.0.toString()`让我的眼睛痒. (25认同)
  • 127.0.0.1.toInt() (18认同)
  • @ Gorilla3D:是的,但这不是一个奇怪的语言功能,是吗? (13认同)
  • 也在Python中以这种方式工作(尝试`3 ..__ add __(4)`).然后我再次认为`(3).__ add __(4)`是一个不那么受脑损伤的方法:) (8认同)
  • 您也可以使用`3.toString()`或`(3).toString()`. (2认同)

Xav*_*avi 130

在JavaScript中:

2 == [2]

// Even stranger
2 == [[[2]]]

// And down-right nutty
var a = { "abc" : 1 };
a[[[["abc"]]]] === a["abc"]; // this is also true
Run Code Online (Sandbox Code Playgroud)

幸运的是,stackoverflow.com的善良的人向我解释了整个事情: 为什么在JavaScript中2 == [2]?

  • @Andrey除了如果我必须保持代码符合你的建议,我很快就会希望它的作者死亡. (36认同)
  • 这很有用,如果你有一个返回数字的函数,并且想要用它返回一些额外的元数据,你可以返回[number]并添加一些额外的字段.简单代码永远不会知道它不是实数,其他代码可以获得所需的元数据. (10认同)
  • 这就是你应该使用`===`的原因. (6认同)
  • +1:我认为自己是一个知识渊博的js程序员,我从来不知道这个:D (5认同)

Jam*_*son 126

我最讨厌的功能是任何包含条件逻辑的配置文件语法.这种事情在Java世界中很普遍(Ant,Maven等等.你知道你是谁!).

您最终只能使用ac**p语言进行编程,调试有限且编辑器支持有限.

如果您的配置中需要逻辑,那么使用真实语言编写配置的"Pythonic"方法要好得多.

  • 我们只是称之为正确. (46认同)
  • AMEN.如果您的配置或构建语言是完整的,那么您做错了.我在看着你的CMake/autotools. (30认同)
  • Tcl在Python诞生之前很久就重新发明了,Lisp在此之前发明了它.所以我们不要称之为Pythonic,我们称之为Emacs-ish. (24认同)
  • 这正是Lua最初设计的目的 (16认同)

Don*_*son 113

powerbasic(www.powerbasic.com)包含编译器指令:

# BLOAT {bloatsize}
Run Code Online (Sandbox Code Playgroud)

这会增加编译后的可执行文件的大小<bloatsize>.如果创建可执行文件的人不喜欢生成的可执行文件的小尺寸,则将其放入编译器中.它使得EXE看起来更大,可以与臃肿的编程语言竞争:)

  • 这让我想起了我最近读到的一些东西.他们正在测试FPS,并决定增加坏人的生命值.然后他们向测试人员询问他们是如何AI的,他们发誓它更聪明.但人工智能没有改变,只有生命值.人们对他们头脑中的世界有一定的叙述,如果你理解并符合他们的期望,他们就会认为它能够证实他们的叙述. (42认同)
  • 哈哈玉.我听说开发人员故意放慢一些操作(例如搜索),因为它可以帮助人们相信它确实在做某些事情.我猜是类似的事情. (9认同)
  • @Nate CK,如果AI长得足以炫耀它的AI,它*可能*实际上*更聪明,而在此之前它可能已经死得太快而无法证明它. (7认同)
  • 我曾经为我的程序添加了很多额外的减速功能,使它们看起来像是在做一些复杂的事情.回到小学,就是这样. (5认同)
  • 回到学校我们有80286机器,我实际上不得不在汇编中编写一些屏幕输出例程以获得合理的速度(即不爬行). (3认同)
  • @asmeurer:不,你走另一条路.更大的可执行文件显然意味着更多功能,对吗 (2认同)

Dou*_* T. 97

在PHP中,函数名称不区分大小写.这可能会让您认为php中的所有标识符都不区分大小写.再猜.变量区分大小写.WTF.

function add($a, $b)
{
    return $a + $b;
}

$foo = add(1, 2);
$Foo = Add(3, 4);

echo "foo is $foo"; // outputs foo is 3
echo "Foo is $Foo"; // outputs Foo is 7
Run Code Online (Sandbox Code Playgroud)

  • 类也不区分大小写. (3认同)

Jes*_*sse 95

在上下文中连续使用两个冒号时,我一直非常喜欢抛出的PHP错误:

解析错误:语法错误,第3行的/path/to/file/error.php中的意外T_PAAMAYIM_NEKUDOTAYIM

我第一次遇到这个时,我完全糊涂了.

  • PHP错误的+1不是英文(在这种情况下是希伯来语). (36认同)
  • 我说希伯来语,我第一次看到它时并不明白! (24认同)
  • 但至少你可以谷歌看到它,我的意思是它是一个非常独特的术语:) (11认同)
  • 翻译是"双点,两次"的翻译. (8认同)
  • 我真的想把它展示给一个"犹太人做了9/11"的阴谋.他们认为这证明了网络是由犹太复国主义者秘密进行的. (7认同)

S.L*_*ott 90

在C.

a[i++] = i;
Run Code Online (Sandbox Code Playgroud)

它编译,但它很少做你认为它应该做的事情.优化变化导致产生截然不同的结果.它在不同的平台上运行方式不同.

然而,编译器对它非常满意.

  • ..但语言不是.在表达式中修改的表达式中的某些内容的多个引用是未定义的行为. (86认同)
  • 这是C允许低级编程这一事实的必然结果,但CPU响应低级错误会做不同的事情.如果C已经定义了所有行为,那么x86上的C将会很慢,因为它会尝试模拟来自PDP-7的边缘情况.如果您不喜欢它,则可以使用完全定义的行为为特定体系结构编写程序集,或者不编写低级代码.虽然实际上说"C的wtf是一种可移植的低级语言",但似乎有点奇怪.这应该不足为奇,因为这是它的目的. (29认同)
  • "为什么未定义的行为会编译并运行?" 通常,因为在编译时无法检测到导致C中UB的某些内容,并且在运行时检测它们(或定义行为)会显着影响性能.在这种特殊情况下,我认为编译器通常不会检测到错误,这有点微弱.它肯定会结束很多这些论点.但同样地,我不打算向gcc提交补丁以发出警告.据推测,您的编译器的作者正在处理其他事情,如果C语言强制要求此代码出错,则会被推迟. (20认同)
  • 使用`-Wall`标志,gcc警告这个'警告:'i'上的操作可能是未定义的 (20认同)
  • @cschol:"编译器(或他们的制造商)通常假设你知道"这正是C的WTF. (13认同)
  • `a [i ++] = i`显然是UB,otoh`a [(*p)++] =*q`是UB,取决于p和q是否指向同一个对象; 在运行该东西之前你无法分辨哪个,因此编译器在一般情况下实际上无法做任何事情.另一个例子:如果分母为零,除法是UB,但你期望编译器用`x/foo(69)`做什么? (6认同)
  • @Richard.为什么未定义的行为会编译并运行?这是我的观点.这是C语言最奇怪的功能.而这个特殊的代码块是我用来以有形的方式总结这个奇怪特征的方法.它有时会导致C n00bs的争论声称具有明确的含义. (5认同)
  • "未定义的行为"意味着编译器可以正确处理此代码和/或发出任何警告或错误.这就是为什么重要的,特别是在C的情况下,要注意语言的任何未定义或未指定的行为(如ANSI-C标准的附件中所规定).编译器(或其制造商)通常假设您知道. (5认同)
  • 未定义的行为就是这样,它是未定义的.这并不意味着它是非法的,只是你不能指望所有实现中相同的*定义*行为. (4认同)
  • "未定义的行为在语言中相当常见"并非如此.我曾经使用过很多语言; C以最糟糕的方式出现这个问题,导致无穷无尽的WTF.像Java这样的一些现代语言根本没有这种"UB"概念.事情要么被定义要么被禁止,或者是等待修复的错误. (2认同)
  • @ S.Lott:除此之外它更深.正如sgm指出的那样,很容易编写可能会产生编译器无法捕获的未定义行为的代码,除非我们想要为`x/0`定义行为,这会严重减慢某些计算机上的划分,无论定义.我们都知道C有很多UB问题,但我们似乎错过了根本原因. (2认同)

Gab*_*yer 80

Python 2.x

>>>True = False
>>>True
False
Run Code Online (Sandbox Code Playgroud)

你真的可以让这个人变得疯狂.

  • 你不能再在Python 3.x中这样做了.它给出了语法错误. (9认同)
  • 这搞砸了,很搞笑.两倍的乐趣,"真,假=假,真".令它倍加可怕的是,之后`1 == 1`仍然返回True.如果True和False只是简单的一致(全局)标签,那就没什么大不了的了 (7认同)
  • 嗯.我认为这可能是"我为什么要使用Python 3?"之类问题的答案.(例如http://stackoverflow.com/questions/1921742/python-should-one-start-a-new-project-directly-in-python-3-x) (3认同)

ray*_*d09 72

Oracle有几个SQL WTF问题.

  1. Oracle将空字符串视为null.

  2. 在"<>"比较中处理空值.

    create table wtf (key number primary key, animal varchar2(10));    
    insert into wtf values (1,'dog');
    insert into wtf values (2,'');
    insert into wtf values (3,'cat');    
    select * from wtf where animal <> 'cat';
    
    Run Code Online (Sandbox Code Playgroud)

返回的唯一行是(1,'dog')行.

  • 两者之间的实际区别在于''是一个价值.NULL不是. (109认同)
  • 字符串'''`不应该被视为NULL,而不应该是整数'0`. (64认同)
  • 我*希望*SQL Server将空字符串视为NULL.毕竟,两者之间有什么实际区别?我的DB充满了CHECK(Name <>''). (6认同)
  • Andrey Shchekin:生命的意义是什么? (6认同)
  • 值是已知数量,数量或测量值,数字或其他.例如,如果没有特殊指令,则"特殊指令"字段可以是'',如果该字段尚未填充则为NULL. (6认同)
  • 什么!?我很高兴我们不使用Oracle.那太可怕了. (4认同)
  • _字符串''不应该被视为NULL,而不应该是整数0_我已经看到更多的情况,当0在逻辑上与NULL不同时比'是'.实际上,当''是可空字符串字段的有效值并且与null不同时,我还没有看到单个业务案例. (4认同)
  • @Andrey Shchekin:真实世界的例子:中间名.NULL - 中间名称未知.空字符串 - 人没有中间名. (4认同)
  • 在涉及文本的地方,NULL表示"我们还不知道这个值." 空字符串表示"我们知道它没有值".如果您有汽车清单,了解哪些汽车没有车牌以及哪些汽车尚未输入许可证号是很有价值的.断言两辆车的牌照号码你不知道牌照的车牌上没有相同的号码也是有效的,但两辆没有车牌的车辆也是如此. (3认同)
  • @Mark Roddy:只需使用`SELECT*FROM wtf WHERE ISNULL(animal,'')<>'cat'`,就像在任何RDBMS中一样. (2认同)

bri*_*gge 70

Java有一本关于它们的完整的书.

预订http://www.javapuzzlers.com/lg-puzzlers-cropped.jpg

Java Puzzlers

  • 我喜欢那些书. (2认同)

Bre*_*ton 70

在JavaScript中,void它不是关键字,它不是类型声明,也不是变量名,它也不是函数,也不是对象.void是一个前缀操作,类似-,--,++,和!.您可以将其作为任何表达式的前缀,该表达式将计算为未定义.

它经常用于bookmarklet和内联事件处理程序,如在这个有点频繁的例子中:

<a href="javascript:void(0)">do nothing</a>
Run Code Online (Sandbox Code Playgroud)

它在这个例子中使用的方式使它看起来像一个函数调用,当它真的只是一个过于聪明的方式来获得原始undefined值.大多数人并不真正理解voidJavaScript中的真实本质,这可能导致许多令人讨厌的错误和奇怪的意外事情发生.

不幸的是,我认为void运算符是获得undefinedJavaScript值的唯一真正有保证的方法,因为在另一个答案中指出,未定义的是一个可以重新分配的变量名,并且{}.a可以通过Object.prototype.a = 'foo'

更新:我想到了另一种生成方式undefined:

(function(){}())
Run Code Online (Sandbox Code Playgroud)

呃,虽然有点冗长,但回归"未定义"的目的却更为明显.

  • @hasen j:将`tabindex = 0`添加到这些元素,否则它们将无法通过键盘访问. (3认同)
  • 为什么不直接使用变量呢?`var foo;`变量被赋值为`undefined`的默认值,无论变量"undefined"是什么.正如已经指出的那样,函数参数也是如此. (3认同)
  • 我只是使用href ="#somemeaningfulfragmentid",当我分配一个点击处理程序时,我得到它返回false.我经常可以在片段ID中编码一些有用的东西,我可以在点击处理程序中检索它.然后,如果javascript被禁用,如果有一个具有相应id的元素,链接仍然可以做一些有用的事情 - 浏览器可以滚动到它.或者,链接指向常规页面,该页面尽可能地再现javascript功能. (2认同)

Mot*_*tti 69

Perl有yada yada运算符(...).

Perl 6遗产的所谓"yada yada"操作符是标记未实现代码的快捷方式:

if ($condition) { ... }
Run Code Online (Sandbox Code Playgroud)

是相同的

if ($condition) { die "not yet implemented" }
Run Code Online (Sandbox Code Playgroud)

  • ack"尚未实施"更易于维护. (5认同)

Alo*_*hal 68

在fortran(肯定是77,也许在95中),未通知的变量和以Ithrough 开头的参数N("in"组)将是INTEGER,而所有其他未声明的变量和参数将是REAL(source).结合"在某些情况下可选的空格"导致了最着名的错误之一.

正如Fred Webb alt.folklore.computers在1990年所说:

我的1963年夏季曾在美国宇航局我工作中的小组正在做的任务控制中心的计算机系统和程序的前期工作.我的办公室伙伴负责测试在水星飞行期间使用的轨道计算程序.通过它运行一些已知答案的测试数据,他得到的答案很接近,但不够准确.因此,他开始在算法中寻找数值问题,检查以确保他的测试数据真的正确等等.

经过几周没有结果,他发现了一个DO 声明,形式如下:

DO 10 I=1.10
Run Code Online (Sandbox Code Playgroud)

编译器(正确地)将此语句解释为:

DO10I = 1.10
Run Code Online (Sandbox Code Playgroud)

程序员明确意图:

DO 10 I = 1, 10
Run Code Online (Sandbox Code Playgroud)

更改.,程序后,结果正确到所需的准确度.显然,该计划的答案对于亚轨道水星飞行来说已经"足够好"了,所以没有人怀疑有虫子,直到他们试图获得更高的准确度,期待后来的轨道和月球飞行.据我所知,这个特殊的错误从未被指责为太空飞行的任何实际失败,但这里的其他细节似乎足够接近我确信这一事件是DO故事的来源.

我认为这是一个很大的WTF如果DO 10 I被视为DO10I,而反过来,因为隐式声明被认为是类型REAL.这是一个很棒的故事.

  • 除非宣布INTEGER,否则GOD是真实的. (54认同)
  • F90 +也有这个"功能",但您可以使用`IMPLICIT NONE`语句来抑制它.此外,隐式类型也适用于函数名称; 我花了一个特别不愉快的夜晚试图找出为什么我为数值方法课程编写的`INTEGRATE`函数总是返回0. (7认同)
  • Fortran忽略了*all*whitespace!`DO10I = 1.10`和'DO 1 0 I = 1.1 0`被视为相同! (3认同)
  • 好极了,亚当. (2认同)

joe*_*eld 63

我最喜欢的小C++语法技巧是你可以将URL(有一些限制)直接放入代码中:

int main( int argc, char *argv[] )
{
    int i=10;

    http://www.stackoverflow.com
    return 1;
}
Run Code Online (Sandbox Code Playgroud)

编译得很好.

语法突出显示有点破坏了笑话,但它仍然很有趣.

  • 我花了一点时间才得到这个,但这很有趣. (5认同)
  • @Serg:`http:`是一个GOTO标签,它定义了当前范围内你可以通过调用`goto http;`跳转到的位置. (3认同)

xcu*_*cut 58

我不敢声称XML是一种编程语言,但它不是我们的心脏吗?:-)

在我看来,XML中最奇怪的特性是以下是一个格式良好的文档:

<_....>
</_....>
Run Code Online (Sandbox Code Playgroud)

这是允许连续点的NT-Name的词汇定义.

  • 如果我正确阅读规范,我也可以将`<: - D> .. </: - D>`作为标记.太好了,我马上就要滥用这个! (95认同)
  • 所以通过给笑脸给一个帽子*(`C`)*它应该是有效的吗?`<o_o> OMG </ o_o>`直接有效' (15认同)
  • 混淆为"<_> <:>:_>:/:_ <:</:> </ _>的+1 (13认同)
  • Esko:这不会很有效,因为命名空间规范会阻止你在它之前没有前缀的冒号:)你必须在冒号之前放置至少一个有效的起始字符.XML不需要像Java那样的导航编程语言(例如foo.bar); 为什么他们没有进一步限制词汇定义,我不知道.懒惰?或者他们只是不在乎. (7认同)
  • 如果你不把XML远离你的心脏,那么它会切断你,而你会流血.一千个尖括号的死亡. (3认同)

And*_*kin 57

继承Ruby中的随机类:

class RandomSubclass < [Array, Hash, String, Fixnum, Float, TrueClass].sample
   ...
end
Run Code Online (Sandbox Code Playgroud)

(首次见于Ruby的隐藏功能)

  • 它看起来更像是语言设计的副作用,顺便说一句很好的例子 (11认同)
  • 在Python中也可能:`class C(random.choice([A,B])):`;-) (7认同)
  • 可能在大多数动态语言中都有可能.例如在Perl中:`package C; 使用base(qw/AB /)[int(rand(2))];` (2认同)

Mot*_*tti 55

令我惊讶的是,您可以通过修改其@ISA数组来更改Perl中的类的继承链.

package Employee;
our @ISA = qw(Person);
# somwhere far far away in a package long ago
@Employee::ISA = qw(Shape); 
# Now all Employee objects no longer inherit from 'Person' but from 'Shape'
Run Code Online (Sandbox Code Playgroud)

  • 我没有看到什么是奇怪的 - 它只是一种动态的语言,正在做它被告知要做的事情.它可以实现许多有用的东西,比如Class :: MOP. (8认同)
  • 它被称为元编程.能够改变课程(通过添加父母,方法等)作为课程的一部分.对于调试(比如将Logger父类添加到任何现有类)和扩展等内容非常有用. (7认同)
  • @David:是的,那是因为大多数语言没有将面向对象的方面嫁接到语言上作为事后的想法. (6认同)
  • 哎呀.确实如此?真的很奇怪!!:) (5认同)
  • 如果我没记错的话,这也可以在Objective-C中实现.我认为Cocoa/GNUstep中的KVO通过在运行时动态子类化观察对象来拦截访问器方法.对象的`isa` /`class_pointer`被更改为新创建的子类. (3认同)
  • 在某些方面,与在`for`循环中更改索引变量相比,这并不奇怪.当然,大多数语言都没有公开面向对象的方面(参见Common Lisp元对象协议). (3认同)

Gor*_*iro 54

我喜欢JavaScript这样的事情:

var futureDate = new Date(2010,77,154);
alert(futureDate);
Run Code Online (Sandbox Code Playgroud)

从2010年第0个月的第0天起,即2016年11月1日,结果为77个月和154天

  • 我其实很喜欢. (32认同)
  • 而且这里的某些东西应该是错的?它只是自动规范化日期.虽然当数字是数学结果时使用这种方式并没有多大意义,但它可能很有用. (15认同)
  • 哦,天哪,那太可怕了.在计算机为我计算日期之前,我必须计算它的日期! (13认同)
  • 我曾经处理过的一个程序在时间戳类上有这个"功能",但只有几小时/分钟/秒.天/月/年被限制在正常范围内.当人们进入像"25:70:99"这样的时间时,它会让我感到非常悲痛,它会在第二天将它们转换成某种东西,而不是像我预期的那样抛出错误.我同意此功能非常有用,但应该选择加入. (3认同)

mik*_*iku 45

在ruby/python/c中,您可以像这样连接字符串:

a = "foo" "bar"
print a # => "foobar"
Run Code Online (Sandbox Code Playgroud)

  • 这不是WTF ---这太棒了 (82认同)
  • 在C中也没有? (79认同)
  • 哦耶.如果你在C中有一个可变参数函数并忘记两个符号常量之间的逗号,这很有趣.所有参数都被一个偏移,并且崩溃了.但在例如ObjC中很好,你可以使用@""__ FILE__来获取带有文件名的NSString. (18认同)
  • @redder:只要它们是恒定的字符串 - 是的. (12认同)
  • 在Python中,这不是"字符串连接" - 它是解析代码的一部分.这是在解析("编译")时间发生的几个问题,而不是运行时间.因此,打印"a"+"b"并打印"a""b"产生相同的结果,但基本上是不同的东西 - 后者应该只用于在多行代码上分割大的字符串常量,(你可以在哪里)不能提供三重报价 - """bla"""由于\n的风格,即是 (6认同)
  • 在Obj-C中作为旁注,当你使用NSString常量(`@""`)时,你不需要任何额外的@s.例如,`@"foo""bar"`.这对于跨行打破字符串非常有用... (3认同)
  • Pfft,sh已经这样做了几十年. (2认同)
  • 字符串**常量**.做``foo"bar`其中bar是包含字符串的变量将不起作用. (2认同)
  • 我只是称它为字符串常量语法,而不是连接. (2认同)

Ate*_*ral 45

在JavaScript中,undefined是一个全局变量,其默认值是原始值undefined.您可以更改以下值undefined:

var a = {};
a.b === undefined; // true because property b is not set
undefined = 42;
a.b === undefined; // false
Run Code Online (Sandbox Code Playgroud)

由于其可变性undefined,通常最好通过typeof以下方式检查undefined-ness :

var a = {};
typeof a.b == "undefined"; // always true
Run Code Online (Sandbox Code Playgroud)

  • "undefined"不是保留字.它是一个变量名,恰好是未定义的.未定义是一种类型,由typeof显示. (23认同)
  • 这也适用于Infinity和NaN.这将在Firefox 3.7中进行更改,顺便提一下:http://whereswalden.com/2010/01/12/more-es5-backwards-incompatible-changes-the-global-properties-undefined-nan-and-infinity-是,现在已经不可改变/ (4认同)
  • 这就是为什么大多数库定义它们的局部范围,如`(function(undefined){...})();`.这样,您的范围内有一个保证的未定义值(因为省略的参数总是未定义).并且它比类型检查更好地压缩. (2认同)

Dan*_*ral 43

在Forth中,任何不包含空格的东西都可以是一个标识符(包含空格的东西需要一些工作).解析器首先检查是否定义了东西,在这种情况下它被称为一个单词,如果没有,则检查它是否是一个数字.没有关键字.

无论如何,这意味着可以重新定义一个数字来表示其他内容:

: 0 1 ;
Run Code Online (Sandbox Code Playgroud)

它创建的 0,组成1,无论在这个被执行的时间.反过来,它可能导致以下结果:

0 0 + .
2 Ok
Run Code Online (Sandbox Code Playgroud)

另一方面,定义可以接管解析器本身 - 这是由注释单词完成的.这意味着Forth程序实际上可以在中途成为完全不同语言的程序.而且,事实上,这是Forth中推荐的编程方式:首先编写要解决问题的语言,然后解决问题.

  • 好吧,我从来没有遇到任何重新定义数字的程序 - 只是因为它可能并不意味着它毕竟是个好主意.但是,有些单词以数字开头,例如`0BRANCH`.至于接管解析器,这很常见,因为该语言非常适合构建DSL. (4认同)
  • 哇.那太疯狂了.它有用吗?还是只是一种痛苦? (2认同)
  • 当我使用Forth时,我试图回想80年代中期.你用接管语言的定义来钉它.因为它正好在Homebrew计算机俱乐部的地方和时间附近,所以有一些真正的角色乱搞Forth和Z80 S100总线等套件计算机.后来Forth是Atari 2600和Commodore 64上的6502会议的替代品 - 现在的孩子们没有想法,总可用内存为64k.而已! (2认同)

Dan*_*reb 43

我在1977年左右将"格式"函数添加到Lisp,之后"printf"甚至存在(我从与Unix相同的来源复制:Multics).它开始时天真无邪,但充满了功能后的功能.当Guy Steele进行迭代和相关功能时,事情就失控了,这些功能已被Common Lisp X3J13 ANSI标准所接受.以下示例可以在Common Lisp the Language,第2版的第22.3.3节中的表22-8中找到:

(defun print-xapping (xapping stream depth)
  (declare (ignore depth))
  (format stream
      "~:[{~;[~]~:{~S~:[->~S~;~*~]~:^ ~}~:[~; ~]~ ~{~S->~^ ~}~:[~; ~]~[~*~;->~S~;->~*~]~:[}~;]~]"
      (xectorp xapping)
      (do ((vp (xectorp xapping))
           (sp (finite-part-is-xetp xapping))
           (d (xapping-domain xapping) (cdr d))
           (r (xapping-range xapping) (cdr r))
           (z '() (cons (list (if vp (car r) (car d)) (or vp sp) (car r)) z)))
          ((null d) (reverse z)))
      (and (xapping-domain xapping)
           (or (xapping-exceptions xapping)
           (xapping-infinite xapping)))
      (xapping-exceptions xapping)
      (and (xapping-exceptions xapping)
           (xapping-infinite xapping))
      (ecase (xapping-infinite xapping)
        ((nil) 0)
        (:constant 1)
        (:universal 2))
      (xapping-default xapping)
      (xectorp xapping)))
Run Code Online (Sandbox Code Playgroud)

  • 给那里的一个人+1.这个答案令人耳目一新,考虑到过多的袖手旁观的答案,有人感到惊讶C#不像C++那样起作用等等. (19认同)

Nat*_*C-K 42

流行性腮腺炎.有很多WTF功能,我选了一个,if声明.(请注意,我正在使用下面相当冗长的编码风格来容纳那些不懂语言的人;真正的MUMPS代码通常对于不熟悉的人来说更难以理解.)

if x>10 do myTag(x)    ; in MUMPS "tag" means procedure/function
else  do otherTag(x)
Run Code Online (Sandbox Code Playgroud)

这类似于Java中的说法:

if (x > 10) {
  myMethod(x);
} else {
  otherMethod(x);
}
Run Code Online (Sandbox Code Playgroud)

除了在MUMPS中,else语句在语法上不是if块的一部分,它是一个单独的语句,通过检查内置变量来工作$TEST.每次执行if语句时,它都会设置$TEST为语句的结果if.该else语句实际上意味着"如果$TEST为false 则执行其余行,否则跳到下一行".

这意味着如果x大于10并且因此第一行被调用myTag,并且myTag包含if语句,那么行为else不取决于if它上面的行而是最后if评估的内部myTag!由于这个"功能",MUMPS编码员通常会教这样编写以上代码是安全的:

if x>10 do myTag(x) if 1
else  do otherTag(x)
Run Code Online (Sandbox Code Playgroud)

if 1在第一行的末尾确保$TEST之前控制进行到下一行正确设置.(顺便说一句,这里的间距必须是这样的,else在所有其他位置之后有两个空格和一个空格.间距是奇数,但是一旦你理解了模式,它至少是非常正交的.)

  • 这是我见过的最糟糕的语言设计.我的心向你和你的MUMPS同事们致敬. (28认同)

Cha*_*tni 41

nullsANSI SQL中的三值逻辑.

  • 我既不同意也不反对 (101认同)
  • 我知道有人发表了评论,但它没有显示在查询结果中. (6认同)
  • 鉴于SQL具有NULL,3-VL似乎比失败语句或构成一些不正确的规则更好. (6认同)

Nic*_*oic 41

Python的一切有趣的副作用 - 实际上是一个参考:

>>> a = [[1]] * 7
>>> a
[[1], [1], [1], [1], [1], [1], [1]]
>>> a[0][0] = 2
>>> a
[[2], [2], [2], [2], [2], [2], [2]]
Run Code Online (Sandbox Code Playgroud)

  • 你要求7次相同的物体而不是7次副本.我认为这是正常的,而不是WTF (8认同)
  • 是的,但是我知道我被这几次咬过了 (8认同)
  • 不是来自Python背景,这真的让我失望.+1 (5认同)

Mat*_*ens 41

在JavaScript中,您可以使用双位否定(~~n)替换Math.floor(n)(如果n是正数)或parseInt(n, 10)(即使n是负数).n|nn&n始终产生相同的结果~~n.

var n = Math.PI;
n; // 3.141592653589793
Math.floor(n); // 3
parseInt(n, 10); // 3
~~n; // 3
n|n; // 3
n&n; // 3

// ~~n works as a replacement for parseInt() with negative numbers…
~~(-n); // -3
(-n)|(-n); // -3
(-n)&(-n); // -3
parseInt(-n, 10); // -3
// …although it doesn’t replace Math.floor() for negative numbers
Math.floor(-n); // -4
Run Code Online (Sandbox Code Playgroud)

单个按位取反(~)计算-(parseInt(n, 10) + 1),因此将返回两个按位否定-(-(parseInt(n, 10) + 1) + 1).

更新: 这是一个jsPerf测试用例,比较这些替代方案的性能.

  • 按位运算符会将其输入截断为有符号的32位值.Math.floor(4294967295.1)== 4294967295; parseInt("4294967295.1")== 4294967295; (4294967295.1 | 4294967295.1)== -1; (3认同)

Wil*_*den 39

这不是一个奇怪的功能,但从类型安全的角度来看真的很烦人:C#中的数组协方差.

class Foo { }
class Bar : Foo { }
class Baz : Foo { }

Foo[] foo = new Bar[1];
foo[0] = new Baz(); // Oh snap!
Run Code Online (Sandbox Code Playgroud)

我相信,这是从Java继承的(双关语).

  • 关键不在于它应该阻止我将`new Baz()`添加到`foo`; 相反,它不应该让我首先将数组强制转换为类型`Foo []`.一个`Foo`数组有两个保证:1)从它检索的任何元素都有类型`Foo`,和2)任何类型为`Foo`的对象都可以分配给数组.如果数组的基础类型实际上是"Bar",那么显然不是这种情况. (26认同)
  • Eric Lippert撰写了一系列关于类型差异的文章,其中第二篇文章阐述了数组协方差的问题:http://blogs.msdn.com/ericlippert/archive/2007/10/17/covariance-and-convvariance-in -c-部分两阵列covariance.aspx (11认同)
  • @Kobi:我不跟进.`Bar []`不是`Foo []`的子类型,那么继承和多态与它有什么关系呢?不应该允许这种类型方差的原因是数组允许对其底层类型进行读写操作.只读类型可以是类型协变,而只写类型可以是类型逆变,但读/写类型可能根本不是类型变量. (8认同)
  • 在Scala编程中,第391页讨论了这种行为:"当被问及[为什么Java有协变数组]时,Java的主要发明者James Gosling回答说他们希望有一种简单的方法来处理数组.例如,他们希望能够编写一个方法来对数组的所有元素进行排序,使用如下的签名来获取`Object`数组:`void sort(Object [] a,Comparator cmp){...需要协方差的数组,以便任意引用类型的数组可以传递给这个`sort`方法." (7认同)
  • 不,Java没有模板.模板为使用模板的每种类型生成新代码.C++模板这样做,Java泛型不这样做.Java泛型更类似于C#泛型; 区别在于C#保留有关字节码中类型参数的信息,而Java在编译时将其用于类型检查后丢弃此信息. (4认同)

Tim*_*her 39

我在C中最喜欢的怪异是5 ["Hello World"],但由于那已经发布了,我最近的最喜欢的怪异是Windows版本结构初始化黑客攻击:

void someWindowsFunction() {
    BITMAPINFOHEADER header = {sizeof header};

    /* do stuff with header */
}
Run Code Online (Sandbox Code Playgroud)

那一条细微的线条完成了以下工作:

  1. 声明BITMAPINFOHEADER结构
  2. 简洁地设置结构的"大小"成员,而不用硬编码大小常量(因为许多Window结构,包括BITMAPINFOHEADER,遵循将结构的大小指定为第一个成员的惯例}
  3. 声明结构的版本(因为许多Windows结构,包括BITMAPINFOHEADER,按照声明的大小标识它们的版本,遵循结构定义仅附加的约定)
  4. 清除结构的所有其他成员(结构未完全初始化时的C标准行为).

  • 实际上,我发现这是一个优雅的解决方案,而不是WTF. (13认同)
  • 在什么时候我说它是WTF?最初的问题是"令人惊讶,奇怪,奇怪或真正的'WTF'".对我来说令人惊讶的是,当它将一个很少使用但定义明确的语言行为与一个简单的编码约定结合起来时,它是多么富有表现力. (6认同)

Vik*_*tor 38

Java的; 使所有对象实例都是互斥体.

  • 呃,也许他讨厌给你分配*的每一个对象增加开销,或者观察到如果你基于每个对象锁定你几乎肯定做错了,或者它可以用泛型来完成库而不是加重核心语言语法或... (11认同)
  • 使用JVM运送mutex类会出现什么问题,然后可以在每个同步语句中使用?那会更困难的是什么? (6认同)
  • 也许他讨厌多核/ CPU系统. (5认同)
  • 从1.5开始就有一个专用类:`java.util.concurrent.locks.ReentrantLock`但它可能从一开始就是一个单独的类.大多数对象不需要内置锁,尤其是不可变对象. (3认同)

小智 37

在PHP中,我们可以做到:

System.out.print("hello");
Run Code Online (Sandbox Code Playgroud)

  • 不想相信它.但实际上是有效的,请问例如codepad.org.http://www.jansch.nl/2007/03/09/systemoutprint-in-php/解释了它的工作原理,但它仍然很奇怪(TRWTF是PHP如何吞下对未定义变量的引用并将`UndefinedConstant`视为``UndefinedConstant "`) (4认同)

And*_*kin 36

在JavaScript中:

alert(111111111111111111111) // alerts 111111111111111110000
Run Code Online (Sandbox Code Playgroud)

这对于我在JSON中来回传递的一些64位密钥非常有害.

  • ECMAscript中的所有数字都是`Nubmber`s,它是一个IEEE浮点数. (10认同)

tom*_*_pl 35

else在Python的for循环中.

从Python文档:

for n in range(2, 10):
    for x in range(2, n):
        if n % x == 0:
            print n, 'equals', x, '*', n/x
            break
    else:
        # loop fell through without finding a factor
        print n, 'is a prime number'
Run Code Online (Sandbox Code Playgroud)

输出:

2 is a prime number
3 is a prime number
4 equals 2 * 2
5 is a prime number
6 equals 2 * 3
7 is a prime number
8 equals 2 * 4
9 equals 3 * 3
Run Code Online (Sandbox Code Playgroud)

  • 它有什么作用? (3认同)
  • @Daniel:我相信`else`只有在`for`循环没有**因为`break`语句退出时才会被执行. (3认同)
  • try:else:就像你期望的那样工作(在没有异常的情况下执行); for/white:else:与50%的程序员的直觉不符.我希望它只在for/while循环的主体从未执行时执行,但事实并非如此 - 只有在执行for/while循环内没有break语句时才会执行else子句.困惑了吗? (3认同)

Ima*_*ist 33

一些早期的动态语言(包括,如果我没记错的话,Perl的早期版本)还没有弄清楚什么是好动力和什么是坏动力.所以有些人允许这样做:

1 = 2;
Run Code Online (Sandbox Code Playgroud)

在该声明之后,以下情况将成立:

if(1 + 1 == 4)
Run Code Online (Sandbox Code Playgroud)

  • 或许:`2 = 2.5;`然后`if(2 + 2 == 5)` (14认同)
  • 什么会2 = 1; 5 = 2; 5 + 2 =?是3吗?还是2? (2认同)

wis*_*sty 30

在Python中,函数参数的"编译时间"(或声明时间)评估可能会令人困惑:

def append(v, l = []):
    l.append(v)
    return l


print append(1)
print append(2)

>>> [1]
>>> [1,2]
Run Code Online (Sandbox Code Playgroud)

意图可能是:

def append(v, l = None):
    if l is None:
        l = []
    l.append(v)
    return l

print append(1)
print append(2)

>>> [1]
>>> [2]
Run Code Online (Sandbox Code Playgroud)

此行为对于缓存等内容非常有用,但它可能很危险.

奖励功能:具有可变内容的元组:

a = (1,2,[3])
a[2][:] = [4] # OK
a[2] = [2] # crashes
Run Code Online (Sandbox Code Playgroud)

  • +1,我会说这是Python的主要部分 (8认同)
  • @Roger Pate:每个Python程序员都会在某个时候被这个问题所困扰,之后他们必须不断地将它留在脑海中.这正是构成语言问题的原因(http://www.ferg.org/projects/python_gotchas.html#contents_item_6). (5认同)
  • 你不能'返回l.append(1)`.你必须'l.append(1); 返回l`因为`list.append`没有返回任何内容. (2认同)

Nic*_*ack 29

在PHP中,字符串与函数指针一样好:

$x = "foo";
function foo(){ echo "wtf"; }
$x(); # "wtf"
Run Code Online (Sandbox Code Playgroud)

不幸的是,这不起作用:

"foo"();
Run Code Online (Sandbox Code Playgroud)

  • PHP有这些语法不一致的废话加载,就像你不能这样做,function()[$ index] (13认同)

Dan*_*ral 29

Scala中,没有运算符,只有方法.所以a + b - c实际上是一样的a.+(b).-(c).在此,它等于Smalltalk.但是,与Smalltalk不同,优先考虑.规则基于第一个字符,因此被称为假设的方法*+优先于被调用的方法+*.例外,任何结束的方法=都具有相同的优先级==- 意义!!!=(非假设方法)具有不同的优先级.

所有ASCII字母的优先级最低,但所有非ASCII(unicode)字符的优先级最高.因此,如果您编写了一个is比较两个整数的方法,那么2 + 2 is 1 + 3将编译并成为真.如果你用葡萄牙语写它é,那么2 + 2 é 1 + 3会导致错误,因为它会看到它2 + (2 é 1) + 3.

并且,为了使Scala中的运算符的WTF更加完善,所有以方式结束的方法:都是右关联而不是左关联.这意味着1 :: 2 :: Nil相当于Nil.::(2).::(1)而不是1.::(2).::(Nil).


小智 29

在JavaScript中,方法的结果可以取决于放置样式括号.这是K&R样式,其中大括号放在方法签名之后和return语句之后:

var foo = function() {
  return {
    key: 'value'
  };
}

foo() // returns an object here
Run Code Online (Sandbox Code Playgroud)

现在,如果我将此代码格式化为Allman样式,其中大括号总是放在一个新行上,结果是不同的:

var foo = function()
{
  return
  {
    key: 'value'
  };
}

foo() // returns undefined here
Run Code Online (Sandbox Code Playgroud)

怎么会?在JavaScript中,如果您不自己动手,语言会在每行的末尾自动分号.那么最后一个代码片段真正发生的是:

var foo = function()
{
  return; // here's actually a semicolon, automatically set by JavaScript!
  {
    key: 'value'
  };
}
Run Code Online (Sandbox Code Playgroud)

因此,如果您调用foo(),方法中的第一个语句将是一个return语句,它将返回undefined并且不会执行其他后续语句.

  • 虽然已经在前面提到过(http://stackoverflow.com/questions/1995113/strangest-language-feature/2003277#2003277). (2认同)

And*_*lio 28

其他奇怪的事情:

在C++中,重写虚方法会隐藏该方法的所有其他重载.在Java中,这不会发生.这非常烦人.示例:http://codepad.org/uhvl1nJp

在C++中,如果基类具有公共虚方法foo()且子类具有私有方法foo(),则此私有方法将覆盖另一个私有方法!这样,只需将子类对象指针强制转换为超类对象指针,就可以调用类外的私有方法.这应该是不可能的:它违反了封装.不应将新方法视为旧方法的覆盖.示例:http://codepad.org/LUGSNPdh

在PHP中,您可以定义函数来接受类型化参数(例如,作为某个接口/类的子类的对象),令人讨厌的是,在这种情况下,您不能使用NULL作为实际参数值.示例:http://codepad.org/FphVRZ3S

  • 实际上,如果你提供类型提示参数的默认值`null`,那么它意味着该值可以是"null"或指定类的实例. (16认同)
  • Re:私有foo()重写公共foo(),这是设计和A Good Thing.否则,更改访问限定符可以无声地更改调用哪些方法.它可以以所描述的方式被颠覆是不幸的,但两个邪恶中的较小者. (2认同)

Tim*_*her 27

我最喜欢的C++之一是"公共抽象混凝土内联析构函数":

class AbstractBase {
public:
    virtual ~AbstractBase() = 0 {}; // PACID!

    virtual void someFunc() = 0;
    virtual void anotherFunc() = 0;
};
Run Code Online (Sandbox Code Playgroud)

我从Scott Meyers的Effective C++中偷走了这个.看到一个纯虚拟(通常意味着"抽象")和内联实现的方法看起来有点奇怪,但它是我发现的最好和最简洁的方法,以确保对象被多态破坏.


Dan*_*ral 27

大约20年前,当我上次涉足MUMPS时,这些实现有一些奇怪的局限性.虽然主机MUMPS变得越来越流行,但MUMPS传统上是一种自托管语言:计算机语言,操作系统和数据库在一个包中.

MUMPS主要是关于它的数据库.本质上,一个巨大的多维哈希表,由一个B*树支持,可以非常快速地访问.语言和数据库之间也没有任何障碍:如果你想在那里存储某些东西,你只需在变量前加上一个符号,表明它将被保存到后备存储中.

另一方面,文件系统几乎不存在,对它的支持甚至更少.关于唯一可以做的是将程序从文件加载到内存中,并将内存中的任何内容发送回文件.并且在加载之前最好清除缓冲区,否则它会与先前的任何东西混合在一起.

因此,考虑到它的自托管性质和极端恶劣的文件系统,人们可能想知道这些程序是如何编辑的.事实上,编辑器本身是用MUMPS编写的 - 那么编辑器如何将程序存储在内存中而不用自己编写?

好吧,诀窍是能够将变量的内容作为源代码执行.然后,编辑器将自身加载到变量中,在其中执行,清除内存,然后在内存中加载,保存和编辑文件,始终从变量执行.

添加到这一事实,即所有的命令可以缩短为他们的第一个字母(除在Z命令,缩短为两个字母,这主要是处理文件系统),以及好奇心喜欢的事实,IF(I)设置一个变量,然后经咨询ELSE(E) - 当然,可以通过任何干预I或程序本身来覆盖.第二个想法,我认为整个语言都是WTF.然而,它有一个奇怪的吸引力.

  • 为了说清楚,我喜欢*MUMPS.但我也看到了更糟糕的情况.或者说,看到一些糟糕的事情让那些已经忍受更糟糕的人感到遗憾 - 保持写得不好的单字母命令,传统的MUMPS代码. (2认同)

Dun*_*can 27

在Ruby中,0在条件表达式中的计算结果为true.

  • 在Ruby中,只有`false`和`nil`是假的.我想它避免使用一个幻数假,如果例如0是函数的有效结果,它仍然可以在错误上返回`nil`并在if语句中使用. (12认同)
  • 我认为强制数字到布尔值是一个WTF - 0不应该被评估为布尔值,它应该是一个类型不匹配. (12认同)
  • +1因为它可以是WTF,即使我认为这是一件好事. (9认同)

Chr*_*hof 27

在类C语言(包括C本身)中,您可以使用"向下转到"运算符:

for (x = 20; x --> 0;) {
    print x;
}
Run Code Online (Sandbox Code Playgroud)

这将打印从19到0的数字.

  • 嗯......这不是一个"操作员".`x - > 0`被解析为`x--> 0`. (24认同)
  • 这让它变得奇怪! (4认同)
  • http://stackoverflow.com/questions/1642028/what-is-the-name-of-this-operator (2认同)

Joe*_*ger 27

绝对最差的WTF必须是Cobol改变的GOTO.

语法非常简单:"ALTER label1 TO GOTO label2",但调试运行时意大利面条的结果令人难以置信.

  • 它准确地代表了一些利益相关者的商业模式,当他们说出一些东西但真正意义上的其他东西时.真是个特色!; d (5认同)
  • 这是其中一件事,如果我看到它,我会拔出霰弹枪. (3认同)

Ton*_*ris 26

"Piet是由David Morgan-Mar设计的一种深奥的编程语言,其程序是看起来像抽象艺术的位图."

打印Piet的Piet程序

打印Piet的Piet程序


Axe*_*xel 26

好吧,这个也是我最喜欢的很难找到的bug ...处理以零作为八进制数开头的整数.这导致了一个只在早上8到10之间显示的错误:

有一次,我帮助构建了一个自动回归测试,以便在晚上通过cron执行.它几乎适用于20人团队中的每个人 - 期望一个开发人员每隔一段时间抱怨自动测试失败,但是当手动运行时,一切正常.甚至一旦这可以手动复制.

好吧,原因是,我们根据date命令的输出对统计数据进行了一些计算(在bash中),这只是从早上8点到9点59分失败,因为我们将小时值读作" 08"(这是一个非法的八进制值,而"01" - "07"是有效的八进制值,从"10"开始,所有内容都被视为十进制)...


小智 25

JavaScript日期充满了WTF.

var d = new Date("1/1/2001");

var wtfyear = d.getYear(); // 101 (the year - 1900)
// to get the *actual* year, use d.getFullYear()

var wtfmonth = d.getMonth(); // 0
// months are 0-based!
Run Code Online (Sandbox Code Playgroud)

  • 有没有听说过Java的Date API?一样. (5认同)
  • new String [] {"jan","feb",...} [date.getMonth()] ...可能是对行为的解释.但是,DAY_OF_WEEK是基于1的...我很想听几个月的推理是基于0和星期几,基于1. (3认同)

moo*_*000 23

作为NHibernate的狂热爱好者,当我听到becomeSmalltalk 时,我感到非常激动......

a become: b
Run Code Online (Sandbox Code Playgroud)

它实际上将a对象更改为b,这使得编写延迟初始化代理变得微不足道,因为对a的所有引用现在将引用b.很简约!

我认为它有资格作为一种奇怪的语言特征,因为没有其他语言具备我的知识能力.

  • 每当有人说"没有其他语言有这个"时,我倾向于精神上追加"......除了Common Lisp":http://www.lispworks.com/documentation/HyperSpec/Body/f_chg_cl.htm :-) (31认同)
  • 您可以在Objective-C中执行此操作,请参阅NSProxy(http://developer.apple.com/mac/library/documentation/cocoa/reference/Foundation/Classes/NSProxy_Class/Reference/Reference.html) (2认同)
  • @mookid:在C#存在20年之前有人没有想到这样的功能真是太可惜了......哦等等...... (2认同)
  • 这在"传统的"smalltalk实现中有效,因为所有内容都是通过对象表进行双向间接.我确实记得读到某个地方:在某些ST实现上效率非常低.在实践中,编写陷阱#NotImplemented的"通用"代理机制往往对持久性或需要此类代理安排的其他机制更有用. (2认同)

Rav*_*lau 23

在FoxPro中,如果我没记错的话,每个命令都可以缩写为4个字符,其他一切都被忽略,所以READ,READY,READINESS都是一样的 - 无论前4个字符被忽略之后是什么.向我解释它的人很喜欢这个功能,但我觉得它很令人毛骨悚然.

  • 早期的Infocom游戏(文本冒险)过去也有类似的限制.因此,如果你试图引用一个游戏没想到的对象,有时你会得到一个关于游戏后期会出现的项目的提示.如:> STEAL THE JACKET>你不能在这里看到一个功能强大的手提钻! (4认同)

Dav*_*ley 22

Common Lisp的format功能可以选择将数字打印为罗马数字.

在INTERCAL中,这是您将获得的唯一输出形式.

  • 这是对CL的`FORMAT`的恶意诽谤,它有两个**选项用于打印数字作为罗马数字:一个打印4作为'IV`; 另一个打印4作为'IIII`. (43认同)
  • 格式还可以选择以英语显示数字,或通过使用格式字符指定循环格式参数. (2认同)
  • IIII不是"不正确的",它在1390年使用,它只是不符合"正确的罗马数字"的现代观念.所以,基本上,变量而不是错误. (2认同)

Alo*_*hal 22

在C中,sizeof运算符不评估其参数.这允许人们编写看起来错误但正确的代码.例如,malloc()给定一个类型的惯用方法T是:

#include <stdlib.h>

T *data = NULL;
data = malloc(sizeof *data);
Run Code Online (Sandbox Code Playgroud)

在这里,*datasizeof运算符中不进行评估(dataNULL,如果进行了评估,则会发生坏事!).

无论如何,这允许人们为新手编写令人惊讶的代码.请注意,正确思想中的任何人都不会真正这样做:

#include <stdio.h>

int main()
{   
    int x = 1;
    size_t sz = sizeof(x++);
    printf("%d\n", x);
    return 0;
}   
Run Code Online (Sandbox Code Playgroud)

这不打印1,2因为x永远不会增加.

对于一些真正的乐趣/困惑sizeof:

#include <stdio.h>
int main(void)
{
    char a[] = "Hello";
    size_t s1 = sizeof a;
    size_t s2 = sizeof ("Hi", a);
    printf("%zu %zu\n", s1, s2);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

(只有当人们对数组,指针和运算符感到困惑时才会产生混淆.)

  • sizeof()不评估其内部结构的一个好处是它允许您创建一个扩展到数组的宏,然后计数:#define STRING_ARRAY(...)((const char*[]){__ VA_ARGS__}),( sizeof((const char*[]){__ VA_ARGS__})/ sizeof(const char*)) (2认同)

cmc*_*loh 22

可能已经说过了(也许这对某些人来说不是那么奇怪)但我认为这很酷:

在Javascript中,声明函数接受的参数只是程序员的便利.通过函数调用传递的所有变量都可以通过关键字"arguments"访问.所以以下会警告"世界":

<script type="text/javascript">

function blah(){
alert(arguments[1]);
}

blah("hello", "world");

</script> 
Run Code Online (Sandbox Code Playgroud)

请注意,虽然看起来这些参数可能存储在一个数组中(因为您可以以与数组元素大致相同的方式访问对象属性),但它们不是. arguments是一个Object,而不是一个数组(因此,它们是使用数字索引存储的Object属性),如下例所示(从Crockford的补救JavaScript页面获取的typeOf函数):

argumentsExample = function(){
    console.log(typeOf(arguments));

    anArray = [];
    console.log(typeOf(anArray));

    anObject = {};
    console.log(typeOf(anObject));
}

function typeOf(value) {
    var s = typeof value;
    if (s === 'object') {
        if (value) {
            if (typeof value.length === 'number' &&
                    !(value.propertyIsEnumerable('length')) &&
                    typeof value.splice === 'function') {
                s = 'array';
            }
        } else {
            s = 'null';
        }
    }
    return s;
}

argumentsExample("a", "b");
Run Code Online (Sandbox Code Playgroud)

  • 这里真正的WTF是参数不是数组. (18认同)
  • 是的,我假设其中很多都记录在案......也许不是.它仍然是一个奇怪的语言功能imo. (2认同)

Tho*_*mas 22

Java缓存整数对象实例,范围从-128到127.如果您不知道这一点,可能会出现以下情况.

Integer.valueOf(127) == Integer.valueOf(127); // true, same instance
Integer.valueOf(128) == Integer.valueOf(128); // false, two different instances
Run Code Online (Sandbox Code Playgroud)


Ces*_*Gon 21

在我看来,能够在C#中输出范围内的枚举是非常奇怪的.想象一下这个枚举:

enum Colour
{
    Red = 1,
    Green = 2,
    Blue = 3
}
Run Code Online (Sandbox Code Playgroud)

现在,如果你写:

Colour eco;
eco = (Colour)17;
Run Code Online (Sandbox Code Playgroud)

编译器认为没问题.还有运行时.

有关详细信息,请参见此处

  • @Dykam,@ Roger:我不同意你们两个人的意见.前段时间我提出,枚举(即命名常量的有限列表)和位域可以通过语言中的不同语法机制而不是同一个来实现..NET使用"enum"构造来实现*枚举和位域(可能继承C++传统),但是从语义的角度来看,命名常量列表(一个合适的枚举)和一个可组合的1位值列表整数(位域)是完全不同的东西.不同的东西需要不同的语言结构. (3认同)
  • @Dykam:我不认为C#中的枚举是*只是*整数; 如果它们只是**整数,我们将使用Int32类型的变量来使用它们,而我们不是.相反,我们使用有目的地创建的机制,即Enum类型,它将*some*类型的安全性添加到命名常量的有限列表中.从语义的角度来看,关于枚举的有趣之处在于它们代表了一个价值领域,而不是它们是整数. (2认同)

小智 20

我很惊讶没有人提到大多数类似C语言的真正丑陋的switch-case实现

switch (someInt) {
    case 1:
    case 2: System.out.println("Forgot a break, idiot!");
    case 3: System.out.println("Now you're doing the wrong thing and maybe need hours to find the missing break muahahahaha");
            break;
    default: System.out.println("This should never happen -,-");        
}
Run Code Online (Sandbox Code Playgroud)

好处是新语言得到了正确的实施.

  • +1 OH GOD YES - 他们何时会学习,最好将普通案例作为默认情况(没有双关语)?在没有打破任何优化的情况下,更有意义的是留下突破,并为我们希望实际继续下一个案例的RARE场合设置一个"continue"关键字. (10认同)
  • 我喜欢Delphi处理案例陈述.单行会自动中断,开始会在结束后自动中断文本块. (4认同)
  • 哦,我真的很讨厌新语言改变了行为.现在,当我混合循环并切换它们并将'break`放在习惯之外时,我得到了我永远无法看到代码的错误. (2认同)
  • 达夫的装置_rules_. (2认同)

Pra*_*are 20

x = x + 1

当我是初学者时,这很难消化,现在功能语言不使用它,这更难!

如果你没有看到这是怎么奇怪:考虑等号的声明断言,而不是分配动作,因为你使用的基本代数做的,那么这是说"零等于一个"的等价物.

  • 一种解释是,这实际上是x''= x'+ 1,但时间在编程中是隐含的(从源代码的底部到顶部),而它必须在数学中显式化. (13认同)
  • 您是否在编程之前来自数学背景? (8认同)
  • 有谁知道这是为什么Wirth造成的:= Pascal中的赋值运算符? (3认同)

dan*_*n04 20

Perl的:

可以编写一个完全由标点符号组成的程序.

这怎么可以工作?!

  • 当你有perl时谁需要brainf*ck! (10认同)

Osc*_*Ryz 19

好的,既然问题将处于间歇模式,我将加入"乐趣"

Go(又名Issue9)使用大写字母表示可见性:

  • 如果您用大写字母命名,它将具有公共访问权限.

  • 如果你使用小写,它将受到包保护:

包装外可见:

func Print(v ...) { 
}
Run Code Online (Sandbox Code Playgroud)

包装外不可见

func print( v ... ) {
}
Run Code Online (Sandbox Code Playgroud)

您可以在此原始答案中找到更多信息.

  • 将语言称为问题9的+1 :-D (14认同)

The*_*ian 18

这里有一大堆奇怪的C功能:http://www.steike.com/code/useless/evil-c/


zed*_*doo 18

在Perl中你可以做到:

my $test = "Hello World";
substr($test, 0, 5) = "Goodbye";

print $test;
Run Code Online (Sandbox Code Playgroud)

这可能用其他语言吗?

  • 哇,我真的想在阅读所有这些很酷的技巧后学习Perl. (6认同)

And*_*kin 18

在JavaScript中,!!a第一次看到(作为转换为布尔值的方式).

  • 好吧你还没有遇到过`~~ a`来强制实施. (13认同)
  • @Andrey Shchekin:+ a不做int强制,它只做数字强制. (4认同)
  • 那么你可以用+ a来做int,它也更短. (2认同)

pol*_*mon 18

我喜欢偷偷摸摸C中的八进制值:

int values[8] = { 123, 154, 103, 310, 046, 806, 002, 970 };
Run Code Online (Sandbox Code Playgroud)


Mit*_*tro 18

C++模板机制是Turing-complete:只要您在运行时不需要输入,就可以在编译时进行任意计算.随心所欲.或者你可以轻松编写一个从不编译的C++程序 - 但在语法上是正确的.


Rus*_*llW 17

这是我最喜欢的一个,你可以在没有main()的情况下用Java做println.

这将编译并运行,给出println,但也是一个异常(java.lang.NoSuchMethodError:main)

class Test {
    static {
        System.out.println("I'm printing in Java without main()");
    }
}
Run Code Online (Sandbox Code Playgroud)

  • @Luybomyr Shaydariv:是的,很奇怪.它是可预测的事实并不能解决陌生问题.此问题下列出的大多数"奇怪"语言功能都是完全可预测的. (6认同)
  • 这很奇怪吗?完全可预测的行为.类加载器在查找任何方法之前加载类时会调用类construcor本身.无论是main(String []),还是其他任何方法.而且,整个应用程序可能没有main(String [])方法 - 它取决于应用程序基础结构. (2认同)
  • 添加System.exit(0); 结束将帮助您摆脱NoSuchMethodError (2认同)

Tim*_*Čas 17

这可能已经提到了,但是 -

PHP对八进制值的处理:

$a = 07; // 7 (as it should be)
$b = 08; // 0 (would be an error in any sensible language)
$c = 018; // 1 (again, should have been an error)
$d = 0A; // error (as it should be)
Run Code Online (Sandbox Code Playgroud)

见这里:http://bugs.php.net/bug.php?id = 29676

还要注意关于bug的评论 - Derick将其称为一个功能(如引用"修复"所示),而不是一个bug,他声称它会"在脚本中使用数字的所有情况下显着减慢PHP" - 但是,为什么PHP会为0A引发错误?

我想人们可以写一本关于PHP古怪的书......


Tho*_*mas 17

在Java中你可能会期望

byte b = 0;
b++;
Run Code Online (Sandbox Code Playgroud)

等于

byte b = 0;
b = b + 1;
Run Code Online (Sandbox Code Playgroud)

但事实并非如此.实际上,您会收到编译器错误,因为添加的结果是int类型,因此无法分配给字节变量b.当使用化合物操作者 ++编译器自动插入浇铸在这里.所以

b++;
Run Code Online (Sandbox Code Playgroud)

b = (byte) b + 1;
Run Code Online (Sandbox Code Playgroud)


bri*_*ary 16

VBScript的日期/时间文字(为什么这仍然是如此罕见?):

mydate = #1/2/2010 5:23 PM#

If mydate > #1/1/2010 17:00# Then ' ...
Run Code Online (Sandbox Code Playgroud)

编辑:日期文字是相对的(他们是技术上的文字,然后呢?):

mydate = #Jan 3# ' Jan 3 of the current year
Run Code Online (Sandbox Code Playgroud)

VB.NET,因为它是编译的,不支持相对日期文字.仅支持日期或仅支持时间文字,但假设缺少的时间或日期为零.

编辑[2]:当然,有一些奇怪的角落案例提出相对日期......

mydate = #Feb 29# ' executed on 2010-01-05, yields 2/1/2029
Run Code Online (Sandbox Code Playgroud)

  • 我对DateTime Literals的问题是它们可能含糊不清 - mydate =#10/9/2009 18:35# - 10月9日或9月10日?现在我猜它总是mm/dd/yyyy,但对于非美国用户而言,以dd/mm/yyyy格式表示日期总是很奇怪.在具有Date构造函数的语言中,您至少可以始终引用签名,但我想这与仅在帮助中查找或记忆它没有什么不同.另一方面:日期的整个语言构造似乎非常"沉重".我可以理解为什么Visual Basic有它(Office VBA),但我不会在C#中看到太多用途 (3认同)
  • @Michael Stum:同意.应该使用ISO 8601,只是为了保持清晰.我想语言功能的相对权重在很大程度上取决于它如何影响程序员个人. (2认同)

Blu*_*eft 16

为什么C#的List <T> .AddRange()不允许我添加T的子类型的元素?List <T> .Add()呢!
所有这一切都将是微软的一个额外的代码行:

public void AddRange<S>(
    IEnumerable<S> collection
) where S : T
Run Code Online (Sandbox Code Playgroud)

  • 这不是一个语言功能,因为它是一个框架功能.迂腐,我知道...... (4认同)
  • 由于新的协同和逆变特征,它与C#4.0一起使用. (3认同)
  • @Denis:亲自试试吧.单行代码*确实*解决*这个*特定的例子,因为它基本上模仿协方差(或逆变,我永远不知道哪一个是哪个). (2认同)

Eri*_*ard 16

在C#中,这应该至少生成编译器警告,但它不会:

public int Something
{
    get { return Something; }
    set { Something = value; }
}
Run Code Online (Sandbox Code Playgroud)

调用时,它会导致您的应用程序崩溃,并且您没有获得良好的堆栈跟踪,因为它是StackOverflowException.

  • 它是简单的递归,可以编写一个完全有效的递归计算属性.虽然编译器可能被硬编码以捕获一些非常简单的无限递归情况,但要将其强制为语言中的*规则*,则需要解决停机问题.你是一个糟糕的家伙来解决停机问题吗? (33认同)
  • 我认为这个问题在当前版本的语言中被认为是固定的.如果您的财产是微不足道的,您应该使用自动属性. (4认同)

小智 16

Javascript中的变量/函数声明:

var x = 1;
function weird(){
  return x;
  var x = 2;
}
Run Code Online (Sandbox Code Playgroud)

weird()返回undefined ...即使赋值从未发生过,x也被"捕获".

同样,但并非如此出乎意料

function weird2(){
   var x;
   return x();
   function x(){ return 2 };
}
Run Code Online (Sandbox Code Playgroud)

返回2.


Tom*_*ier 15

我为客户端编写了一种编程语言(用于实验性地驱动自定义硬件),其中包含一些自定义类型(Curl,Circuit,...),每种类型只有2个值.它们可以隐式转换为boolean,但是(根据客户端的请求)可以在运行时更改此类型的常量的确切布尔值.

例如:Curl类型有两个可能的值:CW和CCW(顺时针和逆时针).在运行时,您可以通过简单的赋值语句更改布尔值:

ccw := true
Run Code Online (Sandbox Code Playgroud)

因此,您可以更改这些类型的所有值的布尔含义.


Boz*_*zho 15

ActionScript 3:

当对象使用其接口时,编译器无法识别从中继承的方法Object,因此:

IInterface interface = getInterface();
interface.toString();
Run Code Online (Sandbox Code Playgroud)

给出了编译错误.解决方法是转换为Object

Object(interface).toString();
Run Code Online (Sandbox Code Playgroud)

PHP:

.+运营商.它有其合理的解释,但仍然"a" + "5" = 5看起来很尴尬.

Java(以及IEEE754的任何实现):

System.out.println(0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1);
Run Code Online (Sandbox Code Playgroud)

输出 0.9999999999999999

  • 它不是Java WTF,它是任何正确(!)IEEE754实现的WTF. (9认同)
  • 第一个不是WTF - 对于计算机上的有限精度浮点表示来说,它迟早会吸引大多数人. (8认同)
  • 很好的是PHP没有做Javascript为字符串连接和添加重载`+`运算符所做的事情.在PHP中,如果你看到`+`,你知道你在谈论添加数字.*...(除非你有阵列...)* (3认同)
  • C#只给我1 :) (2认同)

Chr*_*n V 15

Perl充满奇怪而又整洁的功能.

if 可以在语句之前或之后使用,如下所示:

print "Hello World" if $a > 1;    
if ($a > 1) { print "Hello World"; }
Run Code Online (Sandbox Code Playgroud)

对于以下情况也是如此foreach:

print "Hello $_!\n" foreach qw(world Dolly nurse);
Run Code Online (Sandbox Code Playgroud)

  • Ruby允许相同的if结构.这是我最喜欢的语言之一. (8认同)
  • 我实际上喜欢`if`修饰符,因为它使程序更具表现力和可读性.它允许您将语句中更重要的部分(条件或操作)放在另一个之前,因此它很突出.与任何功能一样,如果明智地使用并且不被滥用,它将非常有用. (7认同)

Jef*_*ver 15

当我在大学时,我用一种名为SNOBOL的语言做了一些工作.整个语言虽然很酷,却是一个很大的WTF.

它具有我见过的最奇怪的语法.而不是GoTo,您使用:(label).如果有的话,谁需要:S(标签)(成功/真实时转到标签)和:F(标签)(失败时转到标签/假)并在行检查某些条件或读取文件时使用这些功能.声明如下:

H = INPUT :F(end)
Run Code Online (Sandbox Code Playgroud)

将读取文件或控制台中的下一行,如果读取失败,将转到标签"end"(因为达到EOF或任何其他原因).

然后是$ sign运算符.这将使用变量中的值作为变量名称.所以:

ANIMAL = 'DOG'
DOG = 'BARK'
output = $ANIMAL
Run Code Online (Sandbox Code Playgroud)

将值'BARK'放在控制台上.因为那不够奇怪:

$DOG = 'SOUND'
Run Code Online (Sandbox Code Playgroud)

将创建名为BARK的变量(请参阅上面分配给DOG的值),并为其赋予值'SOUND'.

你看的越多,它就越糟糕.我所发现的关于SNOBOL的最佳陈述(来自链接文本)是"语言的强大功能及其相当惯用的控制流程特性使得SNOBOL4代码在编写后几乎无法阅读和理解."

  • PHP允许这样,$ animal ="dog"; $ dog ="bark"; echo $$ animal; (6认同)
  • 这个语言的名称值得在这里进行投票 (3认同)
  • 有一次我在SNOBOL写了一个课程作业,它根本没有任何乐趣.这种语言迫切需要更好的控制结构,这比只有一种语句(包括标签,主变量/值,模式匹配部分或全部前者,等号,赋值和跳转到的标签)更重要). (3认同)
  • 我还应该提到我的大学没有SNOBOL编译器.相反,我们有一个SPITBOL编译器. (2认同)

Mik*_*ike 15

在PHP中,"true","false"和"null"是常量,通常不能被覆盖.但是,通过在PHP> = 5.3中引入名称空间,现在可以在任何名称空间中重新定义这些常量,而不是全局名称空间.这可能导致以下行为:

namespace {
    define('test\true', 42);
    define('test\false', 42);
    define('test\null', 42);
}

namespace test {
    var_dump(true === false && false === null); // is (bool) true
}
Run Code Online (Sandbox Code Playgroud)

当然,如果你想要你的真实,你总是可以从全局命名空间导入true

namespace test {
    var_dump(\true === \false); // is (bool) false
}
Run Code Online (Sandbox Code Playgroud)


use*_*298 15

在Haskell:

let 2 + 2 = 5 in 2 + 2
Run Code Online (Sandbox Code Playgroud)

收益率5.

  • 这与`(+)=\2 2 - > 5 in(+)2 2`相同 (4认同)
  • 原因非常简单:在haskell中,(就像在大多数其他语言中一样)你可以简单地在本地重新定义一个函数(haskell以与"普通"函数完全相同的方式处理运算符),这样就可以隐藏外部运算符.在此之后,他只是模式匹配值2和2,就像在haskell中常见的那样.例如,`让2 + 2 = 5 in 2 + 3`会产生模式匹配失败. (2认同)

pib*_*pib 14

在PHP中:

echo 'foo' == 0;    // echos '1'
echo 'foo' == true; // echos '1'
echo 0 == true;     // echos '0'
$foo = 'foo';
echo $foo['bar']    // echos 'f'
Run Code Online (Sandbox Code Playgroud)

PHP有一些最烦人的类型强制...


Fah*_*ahd 14

LOLCODE!

整个语言本身.虽然不完全是WTF的事情,但我从来没有遇到过一种语言,这种语言在我脑海中以一种狡猾的卡通声音播放出来.我以前也没有看过代码,想要惊叹"aaaawwww cuuute!"

该程序显示数字1-10并终止

HAI
CAN HAS STDIO?
IM IN YR LOOP UPPIN YR VAR TIL BOTHSAEM VAR AN 10
    VISIBLE SUM OF VAR AN 1
IM OUTTA YR LOOP
KTHXBYE
Run Code Online (Sandbox Code Playgroud)


whe*_*ies 13

在C或C++中,您可以使用Macros获得很多乐趣.如

#define FOO(a,b) (a+b)/(1-a)
Run Code Online (Sandbox Code Playgroud)

如果FOO(bar ++,4)被传入,它将增加两次.

  • 或者`#define false true` (20认同)
  • 我看到有人在stackoverflow上提到`#define private public`. (11认同)
  • `#define而if`(谁需要循环?)`#define void int`("为什么编译器抱怨我的`void`函数没有显式返回?")#define main(argv,argc)(main) (argc,argv)`(没有明显原因切换argv和argc) (9认同)
  • 虽然使用#define可以做一些愚蠢的事情,但是有完全正确的理由来定义它的定义方式.与此处的其他一些条目相反...... (3认同)
  • @wheaties:很久以前,在很远的计算机实验室里,有些人想出了C语言.而C最初没有"无效"; `void`只出现在标准C中.这意味着有很多人想要运行现代C代码的旧编译器,而且#define void int`运行良好,可以在K&R编译器中运行一些C90代码. (3认同)

小智 13

Perl文件句柄式操作符调用.

一开始,有

print "foo", "bar", "baz"; # to stdout
print STDERR "foo", "bar", "baz";
Run Code Online (Sandbox Code Playgroud)

注意夸张的缺少逗号,以便您知道这是一个打印到文件句柄,而不是以字符串方式打印的文件句柄.这是一个肮脏的黑客.

语言升级滚动,他们制作适当的OO文件句柄并x FOO y, z, abc转入FOO->x(y, z, abc).有点可爱.相同的打印语句有效运行

STDERR->print("foo", "bar", "baz");
Run Code Online (Sandbox Code Playgroud)

当你错过一个逗号,或者尝试运行类似hashof $a, $b, $c(没有括号的子程序调用)并且忘记将hashof函数从其实用程序包导入到命名空间时,通常会注意到这一点,并且您会收到一条关于"无法调用方法"的奇怪错误消息'hashof'通过包''字符串$a' '的内容.

  • 处理Perl中的文件句柄是不可思议的尴尬.它们不是标量值或对象,而是第三类缺乏合理的语法支持.因此,创建了一堆像"IO :: Handle"这样的Perl模块,使它们更加合理 - 除了这些对象在真正的文件句柄无处可行.*程序员不需要太多处理文件就是一件好事.* (3认同)

Pau*_*ce. 12

在Python中:

>>> a[0] = "hello"
NameError: name 'a' is not defined
>>> a[0:] = "hello"
NameError: name 'a' is not defined
>>> a = []
>>> a[0] = "hello"
IndexError: list assignment index out of range
>>> a[0:] = "hello"
>>> a
['h', 'e', 'l', 'l', 'o']
Run Code Online (Sandbox Code Playgroud)

这些切片分配也会给出相同的结果:

a[:] = "hello"
a[42:] = "hello"
a[:33] = "hello"
Run Code Online (Sandbox Code Playgroud)


pab*_*ier 12

简单的挑选,Erlang充满了他们.例如,3种形式的标点符号,

a_function(SomeVariable) ->
  statements_end_with_commas(),
  case PatternMatching of
    0 -> now_we_end_with_semicolon;
    true -> except_the_last_one
  end.

%%  Function definitions end with periods!
Run Code Online (Sandbox Code Playgroud)


Bre*_*ton 12

在JavaScript(和我认为的Java)中你可以逃避这样有趣的角色:

var mystring = "hello \"world\"";
Run Code Online (Sandbox Code Playgroud)

如果你想把一个回车放入一个字符串,那是不可能的.你必须使用\n像这样:

var mystring = "hello, \nworld";
Run Code Online (Sandbox Code Playgroud)

无论如何,对于编程语言而言,这都是正常的和预期的.奇怪的是你也可以逃避这样的实际回车:

var mystring = "hello, \
world";
Run Code Online (Sandbox Code Playgroud)

  • @Loadmaster:确定你不是指HTTP?afaik HTML与行分隔符无关 (10认同)
  • 与旧的C语法一样.但请记住,标准HTML需要CR + LF(`"\ r \n"`)换行符. (2认同)

Ima*_*ist 12

更多的平台功能而不是语言功能:在iPhone上,创建一个带有少量计算的无限循环并运行程序.你的手机会升温,外面很冷的时候你可以用它作为暖手器.

  • 除了造纸或投掷导弹外,最佳使用iPhone的+1 (11认同)

tra*_*los 12

在C或C++中,sizeof如果参数不是类型,则括号对于参数是可选的:

void foo() {
  int int_inst;

  // usual style - brackets ...
  size_t a = sizeof(int);
  size_t b = sizeof(int_inst);
  size_t c = sizeof(99);

  // but ...
  size_t d = sizeof int_inst; // this is ok
  // size_t e = sizeof int; // this is NOT ok
  size_t f = sizeof 99; // this is also ok
}
Run Code Online (Sandbox Code Playgroud)

我永远不明白为什么会这样!

  • 它不是一个宏,它是一个运营商.但这并不能解释这种差异. (13认同)

Hel*_*len 12

VBScript中的括号标识符

VBScript有所谓的括号标识符,它是用方括号中包含的标识符,如下所示:

[Foo]
Run Code Online (Sandbox Code Playgroud)

实际上,它们非常方便,因为它们允许您在保留字之后命名变量和例程,调用名称为保留字的第三方对象的方法,并且还在标识符中使用几乎任何Unicode字符(包括空格和特殊字符).但这也意味着你可以和他们一起玩得开心:

[2*2] = 5

[??????????, ???!] = [Hello, world!]

[] = "Looks like my name is an empty string, isn't that cool?"

For[For[i=0]=[0]To[To[To[0]
  [Next[To]([For[i=0])=[For[i=0]
Next
Run Code Online (Sandbox Code Playgroud)

另一方面,如果您忘记这样的语句中的引号,括号标识符可能是一个问题:

If MyString = "[Something]" Then
Run Code Online (Sandbox Code Playgroud)

因为这If MyString = [Something] Then是完全合法的语法.(这就是为什么必须使用带语法高亮的IDE!)


有关Eric Lippert博客中括号标识符的更多信息:


Jai*_*oto 12

C/C++:

高速逆平方根算法采用的IEEE浮点表示(维基百科复制的代码)的优势:

float InvSqrt(float x)
{
    union {
        float f;
        int i;
    } tmp;
    tmp.f = x;
    tmp.i = 0x5f3759df - (tmp.i >> 1);
    float y = tmp.f;
    return y * (1.5f - 0.5f * x * y * y);
}
Run Code Online (Sandbox Code Playgroud)

  • 啊,这是Quake代码中的一个,对吧?喜欢它,虽然它不是一个语言特色...... (6认同)

Adr*_*ski 11

在早期版本的Visual Basic中,没有"返回"语句的函数只是"返回无",没有任何类型的编译器警告(或错误).

当我每天必须处理这种语言时,这导致了最疯狂的调试会话.

  • 哦*男人*这很糟糕.我很高兴他们在VB.NET的后期版本中将其删除了.他们真的应该刚刚创建了VB.Sharp并在​​表上留下了兼容性参数. (3认同)

小智 11

在PHP中,字符串字母不能像在C中一样使用,你需要使用ord()chr()为了从数字转换为char而反之亦然:"a" != 97,但是ord("a") == 97.

虽然,有一个例外:

for ($i = 'a'; $i < 'z'; $i++) {
    print "$i ";
}
Run Code Online (Sandbox Code Playgroud)

将打印字母a到y.就像你期望的那样,就好像它是C风格的数据类型一样.

但是如果测试条件改变为<=它将不会像你想象的那样打印到z,而是a到yz!(共打印676件)

如果你将'z'更改为676项目列表中'z'之后出现的'aa',并<再次更改测试条件,您将看到只打印出"a"!不像你期望的那样.

如果您将增量器更改为$i+=2它将再次仅打印"a"!唯一的方法是按顺序使用$i++,$i++现在它的工作方式与预期的一样.

尽管如此,这在PHP中输出字母az的组合是一种很好的方式,尽管实际上很难使用它.


Nat*_*han 11

Perl中的字符串数学非常奇怪.

$ perl -E '$string = "a"; $string++; say $string'
b

$ perl -E '$string = "abc"; $string++; say $string'
abd

$ perl -E '$string = "money"; $string++; say $string'
monez

$ perl -E '$string = "money"; $string--; say $string'
-1
Run Code Online (Sandbox Code Playgroud)

  • 此外,递增"z"给出"aa". (3认同)

Pau*_*ce. 11

在PowerShell中,您可以重命名变量:

> $a = "some value"
> $b = "a"
> $c = "d"
> Rename-Item variable:$b $c
> $d
some value
Run Code Online (Sandbox Code Playgroud)

间接间接!拿那个,PHP!

文字也有效:

> Rename-Item variable:d e
> $e
some value
Run Code Online (Sandbox Code Playgroud)


sta*_*ker 10

我知道的体面和怪异编程语言的最大集合(今天1313),你会在这里找到:http: //99-bottles-of-beer.net/ 准备看到真正奇怪的东西;-)每个人都应该做他的选择


myk*_*hal 10

红宝石

Time.parse经常假装解析没有失败,now而是返回

require 'time'

Time.parse '2000-01-01 12:00:00'
# -> 2000-01-01 12:00:00 +0100

Time.parse '2000-99-01 00:00:00'
# -> ArgumentError: argument out of range ...

Time.parse 'now'
# -> 2010-08-13 21:26:13 +0200

Time.parse 'yesterday'
# -> 2010-08-13 21:26:18 +0200

Time.parse 'billion years ago'
# -> 2010-08-13 21:26:37 +0200
Run Code Online (Sandbox Code Playgroud)


Dar*_*ron 10

早期的FORTRAN,其中空白并不重要.(反Python!)

DO 20 I = 1, 10
Run Code Online (Sandbox Code Playgroud)

含义:从这里循环到第20行,将I从1变为10.

DO 20 I = 1. 10
Run Code Online (Sandbox Code Playgroud)

含义:将1.10分配给名为DO20I的变量.

有传言说这个漏洞撞毁了太空探测器.


And*_*lio 9

在我看来,这不应该在C++中允许:

class A {
public:
  virtual string foo(){return "A::foo";}
};

class B : public A {
public:
  virtual string foo(){return "B::foo";}
};

int main () {
  B* b = new B();
  // In my opinion the following should not be allowed
  cout << b->A::foo() << endl;  // Will print "A::foo"
}
Run Code Online (Sandbox Code Playgroud)

这似乎是正确的,但这意味着您不能覆盖方法而不允许子类的用户调用原始方法而不是新方法.

只需考虑一个集合的子类,您希望在向集合本身添加元素时增加元素的数量.

一个逻辑解决方案是覆盖add()方法以在添加元素之前增加计数器,但是新集合的用户可以使用旧方法向其添加元素,从而绕过增量并导致元素计数器不同意与集合的实际元素数量.

这在Java中是不可能的.

  • 只是尝试使面向对象的更多例子做了它不应该做的事情.语法非常清楚你是故意调用*base*函数.如果你真的不希望这种情况发生,这两个类很可能不是Liskov-Substitutable,你应该使用不允许这种结构的保护或私有继承,甚至在一个全新的对象中聚合"A",这样A不在外面. (17认同)
  • 你似乎对Stroustrup的态度采取了一种态度.Stroustrup并不担心有可能被误用的功能,只要它们足够有用.C++充满了可滥用的功能. (16认同)
  • 我认为谁曾经两次投票,应该说明他为什么这么做 - 我看不出有什么不妥. (6认同)
  • 有一个简单的解决方案:在基类中使`foo()`受保护(并将其重命名为`foo_core()`或其他东西).然后在基类中定义一个公共非虚拟`foo()`来调用受保护的虚拟文件. (4认同)
  • 慷慨是对的 - 你应该尽量避免公开虚拟方法.这使得基类更容易对派生类强制实施约束(例如,通过模板方法模式).Guru Herb Sutter解释:http://www.gotw.ca/publications/mill18.htm (2认同)

Mak*_*kis 9

Java的访问修饰符对我来说是最近的WTF(因为我必须学习一点).

显然,包比类层次结构更贴心.我无法定义子类可见的方法和属性,但不能定义包中的其他类.为什么我要将课程内容分享给其他课程?

但是我可以定义包内的每个类都可见的属性和方法,但不能定义包外的子类.

无论我怎么想这个,我仍然看不到逻辑.切换访问修饰符并使受保护的行为像在C++中一样工作,并保持包私有修饰符不变,这是有意义的.现在它没有.

  • 逻辑对我来说非常明显:不是一个类,而是一个包是一个维护单元.隐藏来自子类的成员有效地保留了维护者删除或重命名它们的权利,而不会破坏子类中的代码,如果这些子类位于不同的包中,这非常有用,并且可能是在完全不同的时间和地点由完全不同的人编写的.包维护者甚至可能根本不知道子类存在. (11认同)

And*_*kin 9

在C:

warning C4013: 'myfunc' undefined; assuming extern returning int
Run Code Online (Sandbox Code Playgroud)

我记得由于某种原因没有看到警告(在一些遗留代码中太多了吗?)并且令人费解为什么从int转换导致编译器错误,其中使用非int返回函数.

编译器假设这样的东西是非常意外的.


Tom*_*ora 9

从Java中的文本文件中读取一行.

BufferedReader in = null;
try {
   in = new BufferedReader(new FileReader("filename"));
   String str;
   str = in.readLine();
   if (str != null) {
      ...
   } 
} catch (IOException e) {
   ...
} finally {
   try {
      if (in != null) {
         in.close();
      }
   } catch (IOException e) {}
}
Run Code Online (Sandbox Code Playgroud)

啊.虽然我承认这并不奇怪......只是邪恶.:-)

更短,更惯用的版本:

try {
   BufferedReader in = new BufferedReader(new FileReader("filename"));
   try {
       String str = in.readLine();
       while (str != null) {
          str = in.readLine();
       } 
    } finally {
        in.close();
    }
} catch (IOException e) {
    e.printStackTrace();
}
Run Code Online (Sandbox Code Playgroud)

  • Perl的while(<>){print;}从未如此好看. (3认同)

Doc*_*les 9

对我来说,它绝对是PLEASEINTERCAL中的修饰符.如果PLEASE看起来不够频繁,则该程序被认为是不够礼貌的,并且错误消息说明了这一点; 如果过于频繁,该程序可能会被过度礼貌地拒绝.

  • 我使用`please`作为`sudo`的shell别名. (17认同)

Ira*_*ter 9

PHP作为一种完整的语言大多是WTF.

langauge定义(参见www.php.org)不是通过语法或标准来定义的,而是通过一堆"你可以写这个例子 "的部分来定义的(你能写出其他的东西,当然,只是猜测一下这个概括) ),诚实的上帝用户贡献说"但它做了这个wacko事情......".

我经常使用我们构建的PHP解析器遇到故障.这是最新的:

 "abc$A[define]def"
Run Code Online (Sandbox Code Playgroud)

现在,PHP是PERL的一个(真正糟糕的)副本,因此它允许使用隐含的变量替换来构造字符串.字符串中的$ X表示"将$ X的值插入字符串",相当于"abc".$ X. "def"在哪里"." 是PHP的字符串连接运算符.

字符串中的$ A [7]表示"将数组$ A的第七个插槽的值插入字符串",相当于"abc".$ A [7]."高清".

现在,语言(网站)清楚地说"定义"是一个关键字,并且无论何时找到表达式,都无法使用它.所以上面包含"定义"的宝石做了什么?抛出语法错误?不,这是有道理的.

不,它实际意味着:

 "abc" . $A["define"] . "def"
Run Code Online (Sandbox Code Playgroud)

只有在字符串中的简单数组访问中编写看起来像标识符(关键字或不是!)的东西时,它才会执行此操作.语言中没有其他地方会发生此行为.什么,写"abc $ A ["define"] def"是不合理的,所以PHP发明者不得不抛弃它?给我一个休息时间.(为了复合重罪,有一个"字符串中的复杂数组访问",当然它的工作方式不同.请查看"abc {$ A [define]} def";根据PHP网站的说法,这是非法的.

(原来PHP数组是关联哈希,所以按名称查找数组(井,哈希表)成员并不是一个可怕的想法).

语言充满了这样的陷阱.如果你喜欢"哎呀,看看我今天在我的子程序中发现了什么东西",你应该切换到PHP.

  • 考虑到$ a ['test']和"$ a [test]"也是等价的,这是有道理的.但人们确实想知道为什么PHP有这么多的"功能",不会增加任何真正的好处,只会导致意外或不可预测的行为...... (3认同)

Cod*_*ism 9

学习PowerShell时发现:

尝试猜测结果数组的样子:

$a = 1, 2
$b = 1, 2+3
$c = 1, 2*3
Run Code Online (Sandbox Code Playgroud)

回答:

1, 2
1, 2, 3
1, 2, 1, 2, 1, 2
Run Code Online (Sandbox Code Playgroud)

哎哟! 它激起了我对PowerShell及其背后的人的信心.

  • 我理解为什么它这样工作.但不明白为什么它是这样设计的. (9认同)

c-s*_*ile 9

在JavaScript中:

var something = 12;

function nicelyCraftedFunction()
{
  something = 13;
  // ... some other code
  // ... and in Galaxy far, far away this:
  if( false ) // so the block never executes:
  { 
    var something; 
  }
}
nicelyCraftedFunction(); // call of the function
Run Code Online (Sandbox Code Playgroud)

通常你会期望something变量的值为13.但不是在JavaScript中 - 变量有函数作用域,所以后面的声明会影响上游的所有内容.

在使用C/C++/Java表示法(如JS)的语言中,您会期望变量具有块范围,而不是像这样......

因此编译器甚至可以从最终生成的字节码中删除的死代码块仍然会在正常执行的其余代码中产生副作用.

因此something仍然是12- 在调用函数后不会改变.

  • 执行函数后,外部变量"something"不会改变.所以'某事= 13;' 在这个样本中什么都不做.很快JS在函数体中看到'var something'**它会认为它是一个局部(用于函数)变量. (2认同)

riv*_*ver 8

INTERCAL中的一元运算符(AND,OR和XOR).

  • 来自http://en.wikipedia.org/wiki/INTERCAL#Operators:"与大多数其他语言相反,AND,OR和XOR是一元运算符,它们处理其参数的连续位;结果的最重要部分运算符应用于输入的最高有效位和最低有效位,结果的第二最高位是运算符应用于最高和最高有效位...等等.也就是说,所有INTERCAL都是故意的WTF. (13认同)

小智 8

在MUMPS中,你可以有一个带偏移的GOTO.如果你有(我的MUMPS生锈...)

some_label if x=1 do_something
           else  do_something_else
Run Code Online (Sandbox Code Playgroud)

然后是代码

           goto some_label+1
Run Code Online (Sandbox Code Playgroud)

将跳转到ELSE声明......


dvi*_*lli 8

我很喜欢Smalltalk中缺少运算符优先级

2*3 + 4*5 = 6 + 4*5 = 10*5 = 50

代替

2*3 + 4*5 = 6 + 4*5 = 6 + 20 = 26

这是由于smalltalk的对象性质以及消息从左向右传递的事实.如果消息*以3号作为参数发送到2,则该消息的响应为6.非常棒,如果你感觉邪恶,你甚至可以修补它.


Ste*_*ier 8

在SQL中

NULL 不等于 NULL

所以你做不到:

WHERE myValue == NULL
Run Code Online (Sandbox Code Playgroud)

这将始终返回false.

NULL != NULL
Run Code Online (Sandbox Code Playgroud)

  • 这很有道理.我应该有两个值,但我不知道它们是什么.它们的价值是否相同?我不知道. (9认同)
  • @Tom,如果你不知道它是什么,那么它在数据库中做了什么? (3认同)
  • 真正的WTF在SQL中使用`==`. (2认同)

Dan*_*ral 8

Forth的控制结构有些奇怪.首先,因为它是反向抛光符号语言,所以条件先于IF,如:

x 0 = IF
Run Code Online (Sandbox Code Playgroud)

现在,要关闭条件块,可以使用关键字THEN:

x 0 = IF ." Equals zero!" THEN
Run Code Online (Sandbox Code Playgroud)

现在真正的WTF开始了.IF编译条件向前跳转是什么,并在堆栈上放置跳转偏移的地址.当THEN被发现,它从堆栈中弹出该地址,计算实际的偏移量,然后再编译.的ELSE,而另一方面,编译一个inconditional向前跳,从栈中弹出一个地址,在堆栈中压入一个新的地址,计算用于弹出地址的偏移量,然后编译该偏移.意思是语法是这样的:

x 0 = IF ." Equals zero!" ELSE ." Not equal to zero!" THEN
Run Code Online (Sandbox Code Playgroud)

第一个和第二个语句编译如下:

x LITERAL 0 = (0BRANCH) LITERAL offset SLITERAL" Equals zero!" (DOTQ)
x LITERAL 0 = (0BRANCH) LITERAL offset SLITERAL" Equals zero!" (DOTQ) BRANCH LITERAL offset SLITERAL" Not equal to zero!" (DOTQ)
Run Code Online (Sandbox Code Playgroud)

为了加剧这种怪异,这种行为并没有隐藏起来.它是该语言的ANSI规范的一部分,可以通过构建自定义流控制结构或以有趣的方式组合它们来自由地利用它.例如,采取Forth的WHILE循环:

BEGIN x 10 < WHILE x 1+ to x REPEAT
Run Code Online (Sandbox Code Playgroud)

BEGIN和之间的部分WHILE是任意代码,因此您实际上可以在单个控制结构中的条件测试之前和之后执行代码.这是设计,但以下,虽然允许,不是:

BEGIN DUP 2 > WHILE DUP 5 < WHILE DUP 1+ REPEAT 123 ELSE 345 THEN 
Run Code Online (Sandbox Code Playgroud)

这利用了每个控制流字如何工作以组合两个WHILE语句,并且,为了引导,为每个出口添加不同的后循环代码.为了表明我不是在开玩笑,我只是从互联网上的代码中复制了那个小片段,只需稍加修改就可以简化它.


edu*_*ffy 8

在MAXScript中,所有运算符都被视为相等.因此,a = b + c设置a等于b,然后计算总和a+c,并丢弃结果.


seh*_*ugg 8

通知7.有效程序的示例:

    Chomsky is a room. 
    A thought is a kind of thing. 
    Color is a kind of value. 
    The colors are red, green and blue. 
    A thought has a color. It is usually Green. 
    A thought can be colorful or colorless. It is usually colorless. 
    An idea is a thought in Chomsky with description "Colorless green ideas sleep furiously." 
    A manner is a kind of thing. 
    Furiously is a manner. 
    Sleeping relates one thought to one manner. 
    The verb to sleep (he sleeps, they sleep, he slept, it is slept, he is sleeping) implies the sleeping relation. 
    Colorless green ideas sleep furiously. 

可以找到像这个图灵机模拟器的其他愚蠢.


Joe*_*e D 8

C++ 1x Lambda:

[] (int x) { std::cout << x << std::endl; } ();
Run Code Online (Sandbox Code Playgroud)

这些可以被滥用于一些奇怪的语法:

[](){}();[]{[]{}();}();
Run Code Online (Sandbox Code Playgroud)

这是完全有效的C++ 1x.


joa*_*ast 8

到目前为止,我遇到的最奇怪的特征是BASIC方言中的"RETURN n"语句(不记得哪一个,这是大约28年前的事)."n"是可选的,默认为1.它可以是正数或负数,表示相对于调用GOSUB的哪一行是下一个执行的行.

例如,以下将输出"30":

10 GOSUB 200
20 PRINT "20"
30 PRINT "30"
100 END
200 RETURN +2
Run Code Online (Sandbox Code Playgroud)

当我不得不将这个奇怪的BASIC编写的程序翻译成FORTRAN时,我遇到了这个问题.基本程序使用此功能相当多,返回基于各种条件不同的报表,我花了一段时间来理解其中的逻辑流程.一旦我理解了它,我就能编写一个更简单的程序版本.不用说,更简单的FORTRAN版本比原始的BASIC程序具有更少的错误.


小智 8

在PHP中:

for ($s="a";$s<="z";$s++) echo $s.' ';
Run Code Online (Sandbox Code Playgroud)

这将写:

a b c d e .. .w x y z aa ab ac ad .. ay az ba bb bc ... by bz ca cb ... yz za zb ... zx zy zz
Run Code Online (Sandbox Code Playgroud)


dwi*_*del 8

VB.NET的设计者为了保持与Visual Basic 6.0的向后兼容性做了几件非常愚蠢的事情.当然,还不够,它实际上兼容的,只是足以让事情变得更加反直觉.但最糟糕的是你不必初始化变量,因为它们已经存在,除非在极少数情况下它们不是.

    For i As Integer = 1 To 3
        Try
            Dim k As Integer
            k += 1
            MsgBox(k)
        Catch ex As Exception
            MsgBox(ex.ToString)
        End Try
    Next
Run Code Online (Sandbox Code Playgroud)

这将打印1 2 3.

拥有一个你无法信任的功能不是一个功能,这是一个错误.说它是设计的只是使它成为一个设计错误,而不是一个实现错误.

  • 原因是变量的生命周期是每个函数,它与范围不同.我知道以前,我认为在所有.NET中都是如此.对我来说不明显的部分是为什么它会自动重用相同的变量而不是初始化它.可怕的是,我遇到的任何人似乎都不知道这种行为,我在生产代码中看到了这个错误. (3认同)

Bob*_*man 7

我曾经写过一个有"strfry"运算符的编程语言:

"hello world"?
# => "wdo rlholle"
Run Code Online (Sandbox Code Playgroud)

有用,是吗?

  • @Ken:是的,但作为一元运算符,它更有用. (3认同)
  • 嗯?那有多奇怪?我的意思是,它起初看起来像Perl,但后来你意识到它的作用,然后它根本就不奇怪. (2认同)

S.L*_*ott 7

另一个C-ism.

int i= 0;
while( i != 12 ) {
    /* Some comment 
    i += 1;
    /* Another comment */
}
Run Code Online (Sandbox Code Playgroud)

为什么不起作用?林特会告诉你.然而,C编译器通常会轻易地通过它.和我一样

当我弄清楚出了什么问题时,这是一个真正的WTF时刻.

  • 使用指针特别危险:`x =*p/*q;`. (12认同)
  • 我喜欢在SO上突出显示的代码使问题非常清楚! (8认同)
  • @BlueRaja:当我学习C时,IDE还没有被发明.认真.当我学习COBOL时,文字处理器还没有被发明出来.很高兴地说"工具解决了这个问题".他们没有解决问题.他们更清楚地揭露问题.问题仍然存在,Java等语言中的相关问题在帮助n00bs时仍会导致WTF时刻. (4认同)
  • @Michael Stum:是的,错误终止的多行评论是一个完整的WTF.语法高亮,BTW,是一项非常新的技术.它确实有帮助.然而,在发明语法高亮之前,我们中的许多人已经编程了几十年. (3认同)

Pau*_*ce. 7

这是一个缺乏一种特性,它是怪异的:Python中没有switch声明(尽管存在解决方法).

  • 非常奇怪的部分:不知怎的,你永远不会错过它. (25认同)

Pau*_*her 7

在javaScript中,NaN是一个全局变量.

  • 并且未定义!(15chrlmtislame) (5认同)

kri*_*iss 7

我所知道的最奇怪的功能来自C++世界:SFINAE.

最糟糕的是它碰巧实际上非常有用,在BOOST中广泛使用SFINAE对我来说已经证明了.


小智 7

Java Generics是WTF:

List<String> ls = new ArrayList<String>(); //1
List<Object> lo = ls; //2
Run Code Online (Sandbox Code Playgroud)

2:非法(???)这令人费解,但你必须考虑下一步会发生什么:

lo.add(new Object());
String s = ls.get(0);
Run Code Online (Sandbox Code Playgroud)

我们会将一个Object分配给一个String引用,哦,不!像这样,周围有许多陷阱.

  • 我认为Java通过使其数组协变而搞砸了整整一代程序员. (8认同)
  • 关于java泛型的最糟糕的部分是他们不想费心扩展JVM所以他们只是将它全部编码到编译器中...在我看来,这导致了java中的大多数泛型问题. (6认同)
  • 使用java泛型的真实wtf是类型擦除 (5认同)

Maw*_*awg 7

大约20年前,我使用编译器编写了一个名为Coral的语言,它允许我声明writeonly变量!

但这是有道理的,因为它们是全球性的并且用作信号机制.一个进程会写一个值而另一个进程会读取它.

  • 但如果他们是只有变量,那么另一个人如何阅读呢? (12认同)

Dud*_*udu 7

以下C#代码抛出NullReferenceException而不是print 1:

    static void SomeMethod(string format, params object[] args)
    {
        Console.WriteLine(args.Length);
    }

    static void Main(string[] args)
    {
        SomeMethod("blabla", null, "Ok here"); // print 2
        SomeMethod("blabla", null); // exception
    }
Run Code Online (Sandbox Code Playgroud)


Vil*_*ili 7

PHP

从在线文档:
string implode ( string $glue , array $pieces )- 使用字符串连接数组元素
注意:由于历史原因,implode()可以按任意顺序接受其参数.

这样可行: implode($someArray, $glue)

希望他们在PHP 6中消除这些历史怪癖.

  • 要消除PHP的怪癖,需要杀死整个语言= P ......我认为这是一个好主意. (18认同)

小智 6

在Java中

int x = 010;

这将x指定为值8.

在Java中以零开头的任何整数都假定为八进制.

  • 应该说:"在许多编程语言......"因为在C/C++,Perl,PHP,Tcl,Javascript,Ruby,Python中都是一样的......我说这是C的错. (11认同)
  • 这是"在[插入 - 喜欢 - 或者 - 讨厌的语言 - 八进制 - 文字 - 这里]的第0个骗局,010是8".请删除并改进原始答案. (2认同)
  • 什么马蒂纽说.@slebetman虽然我*必须提到Python 3.x删除它.是的,它不会将前导0解释为八进制(您可以使用"0o"前缀,类似于"0x").实际上,具有前导零的数字是错误的. (2认同)

cod*_*and 6

在PHP中,您可以使用sigil和包含变量名称的字符串文字或变量来引用变量,例如:

${'foo'} = 'test';
echo $foo;
Run Code Online (Sandbox Code Playgroud)

这将打印"测试".这种行为的奇怪之处在于你也可以使用非字符串作为变量名,例如:

${array()} = 'test';
echo ${array()};
${NULL} = 'test';
echo ${NULL};
Run Code Online (Sandbox Code Playgroud)

现在我们有变量名为array()甚至是NULL!全部包含字符串"test".

  • `$ {array()}`实际上变成`$ Array`(因为将数组转换为字符串总是返回`Array`).所以你不能在这里使用实际的数组. (3认同)

sme*_*lin 6

C++:

void f(int bitand i){ //WTF
    i++;
}
int main(){
    int i = 0;
    f(i);
    cout << i << endl; //1
    return 0;
}
Run Code Online (Sandbox Code Playgroud)


Oak*_*Oak 6

在Java中,如果x的值是NaN,则x == x返回false并x != x返回true.

  • 这是在NaN的定义中,在任何使用IEE浮点的语言中都应该如此.如果该值不是数字,则它不能等于任何数字. (14认同)

Boz*_*zho 6

JavaScript的:

parseInt('06'); // 6
parseInt('08'); // 0
Run Code Online (Sandbox Code Playgroud)

  • 前缀为0的数字是八进制数. (6认同)
  • 这是违反直觉的,因为在解析Int时,你会期望它以十进制表示法执行并剥离前导零.这导致了很多恼人的错误......谁还需要解析八进制数呢?其他语言(更直观地)默认为十进制,可以用radix参数覆盖. (5认同)

ten*_*our 6

Commodore BASIC的命令快捷方式.基本上大多数命令都有缩写形式,通常是第一个字母+(shift + 2nd letter).但是因为C64上的字符集默认为全部大写,所以这些命令看起来像奇怪的符号.这是一个简短的hello world示例:

Commodore BASIC截图

也许有人有一个更好的例子,实际上有更多的肉,但对于长期计划,这看起来完全荒谬.

以下是缩写列表:http://www.c64-wiki.com/index.php/BASIC_keyword_abbreviation


小智 6

寻找功能?为什么不用语言?

我喜欢PHP,但它似乎总是像这样构建"哦s***!我忘了这个!我们只是为函数添加另一个参数",结果如下:

str_replace($ search,$ replace,$ subject,...)
strstr($ subject,$ search,...)

注意额外的下划线和参数的不同顺序.

这是别的东西

$a = array( 'a', 'b', 'c', 'd');

print_r($a); //Prints array( 0 => 'a', 1 => 'b',    2 => 'c', 3 => 'd');
unset($a[2]); //Destroys the element 2 of the list
print_r($a); //Prints array( 0 => 'a', 1 => 'b',    3 => 'd');
Run Code Online (Sandbox Code Playgroud)


小智 6

在Perl中(没有"使用严格"或"使用警告"):

if(true==undef)
{
    print "True\n";
}
else{
    print "False\n";
}
if(undef)
{
    print "True\n";
}
else{
    print "False\n";
}
if(true)
{
    print "True\n";
}
else{
    print "False\n";
}
Run Code Online (Sandbox Code Playgroud)

打印:

True
False
True
Run Code Online (Sandbox Code Playgroud)


Tör*_*bor 6

在JavaScript中:

1 / 0; // Infinity
1 / -0; // -Infinity
Run Code Online (Sandbox Code Playgroud)

  • 此行为由IEEE754定义 - > http://grouper.ieee.org/groups/754/此规范的其他好奇心是正负NaN:s,+ 0,0和-0. (7认同)
  • 多数民众赞成因为JavaScript被创建^^ COUGH ^^粘在一起^^ COUGH ^^假设大多数用户都是白痴,因此会被无意义的错误搞糊涂.他们不想要的是:"第5行的错误:除以零",WTF这个错误信息意味着????" 他们得到的是"HLP MY PRGM DOSNT WRK !!!" (7认同)
  • 所以呢?它只是epsilon\downto 0和\ epsilon\upto -0的1/epsilon限制 (6认同)
  • 具有讽刺意味的是,它在数学上提供的答案*是正确的. (3认同)

Nic*_*rey 6

C#的默认继承模型赢得了我的投票:

public class Animal
{
    public string Speak() { return "unknown sound" ; }
}

public class Dog : Animal
{
    public string Speak() { return "Woof!" ; }
}

class Program
{
    static void Main( string[] args )
    {
        Dog aDog = new Dog() ;
        Animal anAnimal = (Animal) aDog ;

        Console.WriteLine( "Dog sez '{0}'" , aDog.Speak() ) ;
        Console.WriteLine( "Animal sez '{0}'" , anAnimal.Speak() ) ;

        return ;
    }
}
Run Code Online (Sandbox Code Playgroud)

运行程序会产生以下结果:

狗说'Woof!' 动物说"未知的声音"

获得这种行为应该要求程序员走出程序员的道路.子类实例并没有停止它是什么,因为它已被上传到它的超类型.相反,您必须明确请求预期的(并且几乎总是需要的)结果:

public class Animal
{
    public virtual string Speak() { return "unknown sound" ; }
}

public class Dog : Animal
{
    public override string Speak() { return "Woof!" ; }
}
Run Code Online (Sandbox Code Playgroud)

  • 对于C#设计师来说,这是非常慎重的,并且有充分的理由.Anders Hejlsberg在此解释了原因:http://www.artima.com/intv/nonvirtual.html (5认同)
  • 嗯,那太漂亮了.我在C#中如此深刻,我甚至没有意识到这是不寻常的. (4认同)
  • 它不是C++的相同模型吗? (3认同)

小智 6

C++最令人烦恼的解析:

struct S
{
    S() {} //default constructor
};

int main() {

    S s(); // this is not a default construction, it declares a function named s that takes no arguments and returns S.
}
Run Code Online (Sandbox Code Playgroud)


Ren*_*ger 6

PL/SQL允许声明作为关键字的变量和函数名称.以下是可编译的PL/SQL:

create or replace 
  function function 
  return number  as
  return number;
begin 
  function.return := 4;
  return   return;
end function;
/
Run Code Online (Sandbox Code Playgroud)

这创建了一个名为的函数function.后来:

SQL> select function from dual;

  FUNCTION
----------
         4
Run Code Online (Sandbox Code Playgroud)


msp*_*msp 5

一个意想不到的特性是枚举def列表中的尾随逗号和C,C#,Ruby等中的数组初始化列表.

string[] foods = { "tofu", "grits", "cabbage", }

public enum ArtPeriod {
  Modern,
  Romantic,
  Dada,
}
Run Code Online (Sandbox Code Playgroud)

  • 我发现它非常酷且有用,而不是真的"奇怪". (15认同)
  • 不奇怪.奇怪的是Internet Explorer坚持在遇到尾随逗号时产生错误或彻底崩溃(所有其他javascript解释器都容忍尾随逗号). (4认同)
  • 使用脚本生成列表时非常有用.它消除了删除尾随逗号的麻烦. (3认同)
  • 我总是使用尾随逗号.这样,有人可以轻松地在中间或结尾添加/删除/评论一个枚举值. (2认同)

msp*_*msp 5

在Javascript中,我相信以下内容是等效的:

a['title'] = "Syntactic sugar is good for yr teeth.";
a.title = "Syntactic sugar is good for yr teeth.";
Run Code Online (Sandbox Code Playgroud)

  • 它不是WTF,它非常有用(也是合乎逻辑的). (22认同)
  • 如果您在设计时知道您要求的数据成员但仍允许使用数组语法进行动态访问,那么它会使语法更好一些. (3认同)
  • 有用可能,逻辑很难imo. (2认同)
  • 为什么?因为它不完全像C或PHP? (2认同)

bri*_*ary 5

VBScript的With块:

With xml.appendChild(xml.createElement("category"))
  .setAttribute("id",id)
  .setAttribute("keywords",keywords)
  With .appendChild(xml.createElement("item"))
    .setAttribute("count",count)
    .setAttribute("tip",tip)
    .appendChild(xml.createTextNode(text))
  End With
End With
Run Code Online (Sandbox Code Playgroud)

  • 一个独特的功能不一定是奇怪的....我希望C#和其他语言也有这个功能. (2认同)

Dav*_*ble 5

Javascript中的许多东西可以让你的眼睛流水.

局部变量的范围,只是一个简单的例子:

function foo(obj)
{
  for (var n = 0; n < 10; n++)
  {
    var t;        // Here is a 't'
    ...
  }
  t = "okay";     // And here's the same 't'
}
Run Code Online (Sandbox Code Playgroud)

  • @Maltrap:t在内部块中定义,由{和}分隔.在几乎所有其他现代语言中,块内定义的内容都保留在该块内.同样,我可以认为t是在global/window对象中定义的,并且应该可以全局访问.JavaScripts行为非常奇怪,因为它将范围应用于某些{} -Blocks而不是其他人. (12认同)

rjh*_*rjh 5

MySQL的枚举,特别是它们能够将毫无准备的同事与生活地狱混为一谈.

CREATE TABLE foo (
    ....
    dispatched ENUM('0','1') NOT NULL DEFAULT '0',
)
Run Code Online (Sandbox Code Playgroud)

然后:

UPDATE TABLE foo SET ..., dispatched = 1;
Run Code Online (Sandbox Code Playgroud)

哎呀,dispatched被设置为ZERO,因为没有引用1.这让我的代码工作变得非常恼火; 我现在使用普通的旧INT.

在相关的说明中,即使您向枚举添加空字符串选项,例如

blah ENUM('','A','B') NOT NULL,
Run Code Online (Sandbox Code Playgroud)

如果您指定了无效值blah,MySQL将使用一个秘密隐藏的空字符串值来表示无效值,这将很难与您自己添加的值区分开来.好极了!


use*_*421 5

在X ++(Microsoft Dynamics AX)中:

1)需要在单独的行上使用分号(;)来将变量声明与语句分开(至少最高版本为4.0)

    int i;
    int myArray[5];
    ;
    i = 1;
Run Code Online (Sandbox Code Playgroud)


2)数组索引是从1开始的,因此不允许使用索引0(零)从数组中读取

    int myArray[5];
    ;
    print myArray[0];    // runtime error
Run Code Online (Sandbox Code Playgroud)

这并不奇怪,但你可以在一个分配的左侧使用零索引,就像在

    int myArray[5];
    ;
    myArray[2] = 102;
    myArray[0] = 100;    // this is strange
    print myArray[2];    // expcting 102?
Run Code Online (Sandbox Code Playgroud)

怎么了?无论赋值中使用了什么值,数组都会初始化为默认值.上面的代码输出0(零)!


Aar*_*reP 5

在c#中

Math.Round(2.5)==2
Run Code Online (Sandbox Code Playgroud)

  • "标准和预期"取决于观众.程序员很少是银行家,但很好地指出正在发生的事情. (9认同)
  • 这被称为"银行家的四舍五入",几乎是标准和预期.您始终可以使用Math.Round()方法重载以及其他参数来指定其他舍入方法. (8认同)
  • 它被称为"银行家的四舍五入",但它不仅仅适用于银行家.如果你曾经做过任何统计(或者就此而言是银行业务),你就会知道这种舍入形式有多么有用. (4认同)

Mik*_*ail 5

在MATLAB(面向交互式数组的语言,目前为TIOBE 20)中,有一个关键字end表示数组的最后一个元素(它对应于NumPy -1).所以这是一个众所周知的MATLAB语法:

myVar = myArray(end)
Run Code Online (Sandbox Code Playgroud)

要从数组中间获取元素,通常会写:

myVar = myArray( ceil( length(myArray)/2 ) )
Run Code Online (Sandbox Code Playgroud)

令人惊讶的是,关键字end根本不是关键字,而是一种变量:

myVar = myArray( ceil( end/2 ) )
Run Code Online (Sandbox Code Playgroud)


Fab*_*obs 5

JavaScript中的变量赋值可以创建全局变量.如果变量是在函数内分配的值,并且未var在同一范围内声明它,则隐式声明为全局变量.

function foo() {
  x = "juhu";  // creates a global variable x!
  var y = "kinners"
}

foo();
alert(x); // alerts "juhu"
alert(y); // alerts undefined
Run Code Online (Sandbox Code Playgroud)

请注意,在var为变量赋值后,也可以使用该语句:

function foo() {
  x = 12;
  var x; // x is now local
  return x;
}

alert(foo()); // will alert 12;
alert(x); // will alert undefined
Run Code Online (Sandbox Code Playgroud)


Oli*_*ier 5

在Matlab中,以下内容可能会令人惊讶,特别是如果您习惯使用Python:

>> not true

ans =

     0     0     0     0
>> not false

ans =

     0     0     0     0     0
Run Code Online (Sandbox Code Playgroud)

这里有两个奇怪的功能.第一个被a b解释为a('b'),因此not true被解释为not('true').第二个奇怪的特征是not任何字符返回0(可能是因为没有falsetrue在matlab中,只有0或者1).


dan*_*n04 5

Atari BASIC:

您可以使用字符填充字符串而无需编写循环:

10 DIM A$(100)
20 A$(1)=" ":A$(100)=" ":A$(2)=A$
Run Code Online (Sandbox Code Playgroud)

  • @pedrofurla:我很确定他说在这三个任务之后,A $(3)到A $(99)现在也会包含空格.我敢打赌底层字符串实现看起来像__scary__. (2认同)

jqn*_*qno 5

NSIS(Nullsoft脚本安装系统)具有以下StrCmp指令:

StrCmp str1 str2 jump_if_equal [jump_if_not_equal]
Run Code Online (Sandbox Code Playgroud)

比较(不区分大小写)str1到str2.如果str1和str2相等,则Gotos jump_if_equal,否则Gotos jump_if_not_equal.

StrCmp $0 "a string" 0 +3
 DetailPrint '$$0 == "a string"'
 Goto +2
 DetailPrint '$$0 != "a string"'
Run Code Online (Sandbox Code Playgroud)

锦上添花:jump_if_equaljump_if_not_equal可能是负面的.但我想你已经从+正数前面的符号中找出来了.我不记得它是强制性的,还是只是一个可怕的约定.

这基本上结合了最差的BASIC和最差的汇编程序.


ext*_*eee 5

在Java中

String s = null;
System.out.println(s + "hello");
Run Code Online (Sandbox Code Playgroud)

这输出"nullhello".


小智 5

Python 2.x演示了一个糟糕的列表理解实现:

z = 4
s = [z*z for z in range(255)]
print z
Run Code Online (Sandbox Code Playgroud)

此代码返回254.列表推导的变量与上限定义冲突.

Python 3.x已经解决了这个问题,但是闭包仍然使用动态链接来处理外部变量,并在函数式python程序员中引入了许多WTF

def mapper(x):
    return x*x
continuations = [lambda: mapper(x) for x in range(5)]
print( [c() for c in continuations])
Run Code Online (Sandbox Code Playgroud)

这段代码显然会返回[16,16,16,16,16].


Pau*_*ce. 5

以下类似于这个关于数组的答案.

在Powershell中,与其他动态语言一样,字符串和数字在某种程度上是可以互换的.然而,Powershell无法下定决心.

PS> $a = "4"    # string
PS> $a * 3      # Python can do this, too
444
PS> 3 * $a      # Python doesn't do it this way, string repetition is commutative
12
PS> $a + 3      # Python gives a mismatched types error
43
PS> 3 + $a      # Python would give an error here, too
7
Run Code Online (Sandbox Code Playgroud)

如果变量是整数而不是字符串,则操作是可交换的.

PS> $a = 4      # integer
PS> $a * 3
12
PS> 3 * $a
12
PS> $a + 3
7
PS> 3 + $a
7
Run Code Online (Sandbox Code Playgroud)

如有疑问,请进行演员表演:

PS> $a = "4"
PS> $b = 3
PS> [int] $a * [int] $b
12
Run Code Online (Sandbox Code Playgroud)

你也可以用[float].

  • 让我们看看,Powershell有一个定义明确且合理的策略,用于将整数和字符串与`*`和`+`运算符混合:左操作数定义操作的类型.它碰巧与Python不同.请注意,字符串重复是可交换的"官方"要求,与数字添加不同.然后,数值运算按预期工作.如果将所有内容都转换为单一类型,一切都按预期工作.那么,有什么奇怪的? (4认同)

LLS*_*LLS 5

不确定是否有人提到它.

在Java中,在finally块中它可以返回一个值.它将停止异常的传播并覆盖正常的return语句.


归档时间:

查看次数:

482253 次

最近记录:

12 年,4 月 前