题 最奇怪的语言特征


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

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


975


起源


@gablin我认为如果你使用javascript解析将LISP分隔符与PERL正则表达相结合,你将覆盖90%的WTF ...... - Talvi Watia


答案:


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

a[10]

这很常见。

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

10[a]

这意味着与上述相同。


1861



这是因为[10]表示*(a + 10)...而10 [a]表示*(10 + a):) - Michel Gokan
别忘了“Hello World”[i]。或者我[“Hello World”] - Richard Pennington
或者,更有用的是,“0123456789abcdef”[x&0xf] - Dipstick
@frunsi:它 总是 按预期工作。指针添加与地址上的简单整数添加不同。它是可交换的 不管 有问题的类型是多少。 - R. Martinho Fernandes
@mcv - a [10]与“*(a + 10)”相同,其中表达式“a + 10”是指针算术(并且因为a是短的,在你的例子中,+ 10表示'从'开始a的地址,并移动10个短路,即20个字节')。表达式10 [a]被解释为“*(10 + a)”,其中“10 + a”是 也 指针算术,并以完全相同的方式处理。 - Edan Maor


在JavaScript中:

 '5' + 3 gives '53'

 '5' - 3 gives 2

1296



我记得当我第一次开始使用javascript时使用这种技术在字符串中添加数字:“111” - “222”给出333而“111”+“222”给出“111222”。 - Callum Rogers
+ 对于字符串连接是可怕的 - Matteo Riva
+对于concat不是问题。打字很弱。 - FogleBird
@FogleBird这两个都不是问题所在。这只是 组合 两个强制规则不一致的两个。 - TM.
所以基本上,当涉及到一个字符串时,+是concat。他们为什么不能像'123456'那样编码 - 456 ='123'?那会很有趣。 - Jimmie Lin


在JavaScript中,以下构造

return
{
    id : 1234,
    title : 'Tony the Pony'
};

回报 undefined 是由于在换行符后隐藏的隐式分号插入导致的语法错误 return。以下工作正如您所期望的那样:

return {
    id : 1234,
    title : 'Tony the Pony'
};

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

return /*
*/{
    id : 1234,
    title : 'Tony the Pony'
};

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

return
    2 + 2;

872



分号插入是JavaScript中最邪恶的部分之一。 - fennec
在设计语言功能时,您总是会遇到问题,假设您的用户主要是白痴。 - Rob Van Dam
雅得喜欢这样:评出隐形代码! - RCIX
Nick Retallack:因为JavaScript的C类花括号和分号语法,所以新行很重要。 - Tamas Czinege
如果在使用JavaScript编程时不应该使用C风格,那么选择C风格语法的JavaScript语言设计者则相当不正常。 - Ryan Lundy


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

资料来源:Doug Crockford


797



好的东西Javascript有===运算符,然后。 - Anonymous
那是什么目的呢 == 服务于语言设计师的眼睛? - Chris S
困惑的人。 - Javier
如果,那会很好 == 有意义的 ===,然后有另一个运营商,像 ~= 允许类型强制。 - TM.
@Otto实际上,由于我们正在寻找,他的例子表明==不对称。目前,我没有看到如何为二元关系指定可交换性。 - PeterAllenWebb


C和C ++中的Trigraphs。

int main() {
   printf("LOL??!");
}

这将打印出来 LOL|,因为三卦 ??! 转换为 |


662



快!告诉所有C / b /程序员! - Esteban Küber
Trigraphs是惊人的,因为你可以肯定没有人会发现什么??!将意味着谷歌已经不知道名称。 - zaratustra
默认情况下,在GCC中禁用Trigraph。 - sastanin
这些让你使用“WTF操作符”:( foo()!= ERROR)??!??! cerr <<“发生错误”<< endl; - user168715
当它们被引入时,Trigraphs是必要的邪恶。有些平台只是没有包含某些字符关键字,所以它是“三字母”或“你不能有一个C编译器句末期结束语所以去使用汇编程序”。查看Stroustrup在“The C ++ Programming Language”中的描述。 - Euro Micelli


有趣的自动装箱和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

说明

快速浏览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);
}

注意:  IntegerCache.high 默认为 127 除非由财产设定。

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


574



花了几秒钟才知道为什么...... java必须为-128和128之间的值保留一个Integer实例池,否则它会分配一个新的Integer,对吧? - Mike Akers
但请记住,如果指定new Integer(42),它将不会使用池中的实例,因此foo == bar将评估为false - z -
thedailywtf.com/Articles/The-Integer-Cache.aspx - blu
很高兴我是C#程序员。 - Will
@Will:C#有一些非常相似的陷阱。看到 blogs.msdn.com/jmstall/archive/2005/03/06/386064.aspx - spookylukey


引用 尼尔弗雷泽 (看那页的末尾),

try {
    return true;
} finally {
    return false;
}

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

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

try {
    throw new AssertionError();
} finally {
    return false;
}

373



+1。出于某种原因,我觉得这很有趣,不能停止咯咯地笑。 - outis
谢天谢地,C#不允许这样的疯狂...... Control cannot leave the body of a finally clause - Richard Everett
这返回,假,是吗?它可能看起来像一个WTF(可能它是一个),但我按照规则生活:最后总是赢,除非你之前崩溃机器。 - Michael Stum♦
公平地说,我责怪TDWTF很好的解释,记住最后总是赢,除非你拉电源线: thedailywtf.com/Articles/My-Tales.aspx - Michael Stum♦
在这种情况下,我不确定代码应该返回什么。但我绝对相信你一定不能放 return 在 finally 条款。 - jfs


APL(全部除外), 能够在一行中编写任何程序。

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

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

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

这是一个 视频


325



我喜欢APL。啊,花了整整一个下午写下半行代码的乐趣!当我得到一个可以编程显示字母的键盘时,我要做的第一件事就是再次使用APL重新认识自己。 - Daniel C. Sobral
看起来像希腊人的语言。 - Esko
@Erik:在编写完全与您想要的代码相关的代码时,您会感到高兴,而不是如何到达那里。表达您的代码作为单个表达式。这就像最终的完美武士刀剪裁。当然,在真正的战斗中,我宁愿拿枪。 - Daniel C. Sobral
APL旨在编写,而不是读取。 - lkessler
在一部科幻动作片中看到APL会很棒。我可以想象有人坐在一个三色的终端嘀咕着“重塑敌人的导弹矢量......转置... pi时间对数...升级 - 然后执行!”然后是爆炸和欢呼。 - Joey Adams


可以使用C ++模板的奇怪之处,最好的证明 “多维模拟文字” 它使用模板来计算“绘制”形状的区域。以下代码是3x3矩形的有效C ++

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

          unsigned int c = ( o-----o
                             |     !
                             !     !
                             !     !
                             o-----o ).area;

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

  assert( ( o-------------o
            |L             \
            | L             \
            |  L             \
            |   o-------------o
            |   !             !
            !   !             !
            o   |             !
             L  |             !
              L |             !
               L|             !
                o-------------o ).volume == ( o-------------o
                                              |             !
                                              !             !
                                              !             !
                                              o-------------o ).area * int(I-------------I) );

322



虽然Eelis的模拟文字很棒,但它们是一种奇怪的语言 特征,或者只是一种奇怪的方式 使用 一个特征?
真正的WTF将是由其中一个格式错误生成的编译器错误。 - Andrew McGregor
当有一个版本的AnalogLiterals支持在Eclipse中围绕X,Y和Z轴旋转文字时,再次醒来......现在这会给“视觉编程”一个新的真正含义。 - TheBlastOne
o和L的排序和| s是重要的吗? - Ming-Tang
排序很重要,因为模板会创造性地使用运算符重载。(不要使用实际代码执行此操作,滥用运算符会使代码难以阅读) - josefx