什么模糊的语法毁了你的一天?

时间:2009-02-16 03:09:31

标签: syntax

什么时候遇到可能过时的语法,从未使用过或只是简单的混淆,你无法理解你的生活。

例如,我从来不知道逗号是C中的实际操作符。所以当我看到代码时

if(Foo(), Bar())

我只是吹了一个垫子试图弄清楚那里发生了什么。

我很好奇在其他语言中可能存在一些从不肮脏的角落。

27 个答案:

答案 0 :(得分:21)

C ++的局部变量默认构造函数的语法。起初我写了以下内容。

Student student();  // error
Student student("foo");  // compiles

这导致我通过隐藏的C ++错误消息阅读大约一个小时。最终一个非C ++新手掉了下来,笑了起来,指出了我的错误。

Student student;

答案 1 :(得分:21)

这总是很刺耳:

std::vector <std::vector <int> >
                              ^
                              mandatory space.

答案 2 :(得分:16)

当使用System.DirectoryServices名称空间绑定到ADAM(Active Directory应用程序模式;我认为现在称为AD LDS)时,我试图调试这个简单的代码失去了一整天:


DirectoryEntry rootDSE = new DirectoryEntry(
    "ldap://192.168.10.78:50000/RootDSE",
    login, 
    password, 
    AuthenticationTypes.None);

当我运行代码时,我不断收到错误0x80005000的COMException,这有助于映射到“未知错误。”

我可以使用登录名和密码并通过ADSI Edit绑定到端口。但是这个简单的代码行不起作用。奇怪的防火墙权限?有什么东西搞砸了?某些COM对象未正确注册? 为什么它不起作用?

答案是什么?它是LDAP://,而不是ldap://。

这就是我们喝酒的原因。

答案 3 :(得分:10)

<强> C ++

class Foo
{
    // Lots of stuff here.
} bar;

bar的声明非常难以辨认。更常见于C语言,但在C ++中尤其烦人。

答案 4 :(得分:10)

Perl的语法让我不久前感到糟糕:

%table = {
  foo => 1,
  bar => 2
};

如果没有正确的警告(在我使用的平台上不可用),这将创建一个单元素哈希,其中键作为给定的哈希引用和值undef。请注意{}的微妙使用,它会创建一个新的哈希引用,而不是(),这是一个用于填充%table哈希的数组。

答案 5 :(得分:9)

我很震惊Python的准三元运算符在我第一次看到它时不是语法错误:

X if Y else Z

答案 6 :(得分:8)

这是愚蠢和常见的,但这种语法:

if ( x = y ) {
    // do something
}

在过去的一年中,我用几种不同的语言抓住了我三次。我非常喜欢R语言使用&lt; - 进行赋值的惯例,如下所示:

x <- y

如果x = y语法的意思是x == y,并且x&lt; -y意味着赋值,那么我的大脑将会更顺利地转换为数学和编程。

答案 7 :(得分:7)

C#的?第一次看到它时,操作员把我扔了一圈。基本上,如果LHS为非空,它将返回LHS,如果LHS为空则返回RHS。

object bar = null;
object foo = bar ?? new Student();  // gets new Student()

答案 8 :(得分:7)

C / C ++的bitvector语法。关于这一点最糟糕的部分是试图谷歌只是基于语法。

struct C {
  unsigned int v1 : 12;
  unsigned int v2 : 1;
};

答案 9 :(得分:5)

Powershell的函数调用语义

function foo() { 
  params ($count, $name);
  ...
}

foo (5, "name")

对于那里的非权力出租人。这将有效,但不是你期望的。它实际上创建了一个数组并将其作为第一个参数传递。第二个参数没有明确的价值。正确的版本是

foo 5 "name"

答案 10 :(得分:4)

我第一次在C ++中看到一个函数指针时,我很困惑。更糟糕的是,因为语法没有关键词,所以很难查找。究竟是什么类型的搜索引擎?

int(* Foo)(float,char,char);

我最后不得不向当地的C ++大师询问它是什么。

答案 11 :(得分:4)

VB(是的,我必须使用它)“和”关键字 - 如:

If Object IsNot Nothing And Object.Property  Then

在我确定对象不是NULL之后,看到Object.Property引用?好吧,VB的“和”关键字*确实*不*阻止*进一步*评估,因此代码将失败。

但是,VB确实有另一个关键字 - AndAlso:

If Object IsNot Nothing AndAlso Object.Property Then

这将按照您的预期运行,并且在运行时不会爆炸。

答案 12 :(得分:3)

C的逗号操作符对我来说似乎不太模糊:我一直看到它,如果我没有,我可以在K&amp; R的索引中查找“逗号”。

现在,三卦是另一回事......

void main() { printf("wat??!\n"); }  // doesn't print "wat??!"

维基百科有一些很好的例子,来自真正令人困惑的:

// Will the next line be executed????????????????/
a++;
对于奇怪的有效:

/??/
* A comment *??/
/

甚至不让我开始使用有向图。如果有人可以从记忆中完全解释C的有向图,我会感到惊讶。很快,C有什么有用的图,以及它们在解析时与三字符有什么不同?

答案 13 :(得分:3)

我曾经对一些C ++代码感到困惑,这些代码声明了对局部变量的引用,但从未使用它。像

这样的东西
MyLock &foo;

(让我对语法稍微松懈,近8年来我没有做过C ++)

将看似未使用的变量取出后,程序开始以不明显的方式死亡,看起来与这个“未使用”的变量无关。所以我做了一些挖掘,发现该类的默认ctor抓住了一个线程锁,并且dtor发布了它。这个变量保护代码不会同时进行更新而不会做任何事情。

答案 14 :(得分:3)

不得不将旧的 FORTRAN 中的一些科学代码翻译成C.一些毁了我一天的事情:

打孔卡缩进。每行的前6个字符都保留用于控制字符,转到标签,评论等:

^^^^^^[code starts here]
c     [commented line]

循环的转到式编号(加上6个空格缩进):

          do 20, i=0,10
          do 10, j=0,10
             do_stuff(i,j)

    10         continue
    20         continue

现在想象有多个嵌套循环(即do 20do 30),它们没有区别缩进来知道你所处的上下文。哦,终止语句是数百行。

格式声明,再次使用goto标签。代码写入文件(数字1,2等有用的引用)。要将a,b,c的值写入文件,我们有:

write (1,51) a,b,c

因此,在标有标签51的行上使用格式语句将a,b,c写入文件1:

51      format (f10.3,f10.3,f10.3)

这些format行与他们被称为的地方相距数百行。作者决定使用以下方式打印换行符,这很复杂。

write (1,51) [nothing here]

我很可靠地告诉小组的一位讲师,我很容易。

答案 15 :(得分:3)

Javascript:此语法...

for(i in someArray)

...用于循环遍历数组,或者我认为。一切正常,直到另一个团队成员进入MooTools,然后我的所有循环都被破坏了,因为for(i in ...)语法也覆盖了已添加到数组对象的额外方法。

答案 16 :(得分:2)

在C ++中使用/ clr启用的语法。试图用C ++创建一个托管字典对象。

gcroot<Dictionary<System::String^, MyObj^>^> m_myObjs;

答案 17 :(得分:2)

老人:

在PL / 1中没有保留字,因此您可以使用与语言关键字相同的名称定义变量,方法等。

这可以是有效的代码行:

IF ELSE THEN IF ELSE THEN

(其中ELSE是布尔值,IF和THEN显然是函数。)

答案 18 :(得分:1)

PHP的三元运算符从左到右关联。有一天,当我学习PHP时,这让我非常痛苦。在过去的10年里,我一直在使用C / C ++进行编程,其中三元运算符从右到左相关。

我仍然有点好奇为什么PHP的设计者选择这样做,在许多其他方面,PHP的语法与C / C ++相当接近。

编辑:现在我只能在胁迫下使用PHP。

答案 19 :(得分:1)

AT&amp; T汇编语法&gt; :(

这种反直觉,模糊的语法已经破坏了我的许多日子,例如,简单的英特尔语法汇编指令:

mov dword es:[ebp-5], 1 /* Cool, put the value 1 into the 
                         * location of ebp minus five.
                         * this is so obvious and readable, and hard to mistake
                         * for anything else */

在AT&amp; T语法

中转换为此内容
movl $1, %es:-4(%ebp) /* huh? what's "l"? 4 bytes? 8 bytes? arch specific??
                       * wait, why are we moving 1 into -4 times ebp?
                       * or is this moving -4 * ebp into memory at address 0x01?
                       * oh wait, YES, I magically know that this is
                       * really setting 4 bytes at ebp-5 to 1!

更多...

mov dword [foo + eax*4], 123 /* Intel */
mov $123, foo(, %eax, 4)     /* AT&T, looks like a function call...
                              * there's no way in hell I'd know what this does
                              * without reading a full manual on this syntax */

我的一个favorites

就好像他们采用了操作码编码方案并尝试将其合并到编程语法中(读取:scale / index / base),但也试图在数据类型上添加一层抽象,并将该抽象合并到操作码名称会引起更多混乱。我不认为任何人都可以认真对待这个。

答案 20 :(得分:1)

在对一些C ++代码执行maintentnace时,我曾发现有人做过这样的事情:

for (i=0; i<10; i++)
{
   MyNumber += 1;
}

是的,他们有一个循环,可以将10加1。

为什么它毁了我的一天?行为人早已离开,我不得不修复他们的模块。我以为如果他们这样做了,善良就会知道我还会遇到什么!

答案 21 :(得分:1)

不是很模糊,但每当我用一种语言编写太多代码,然后回到另一种语言时,我就开始弄乱后者的语法。当我意识到C中的“#if”不是注释(而是更致命的东西)时,我总是轻笑自己,并且Python中的行不需要以分号结尾。

答案 22 :(得分:1)

如果我必须阅读/编写许多HP计算器中使用的某种Polish notation,它总是毁了我的一天......

答案 23 :(得分:1)

Iif(condition,expression,expression)是一个函数调用,而不是一个操作符。

条件的双方总是被评估。

答案 24 :(得分:0)

This。我曾多次使用它。

答案 25 :(得分:0)

在用于诉讼文档审查的独立数据库软件(Concordance)的脚本语言(Concordance Programming Language)中,数组被索引,而(某些)字符串函数被索引1。从那时起我就没碰过它了。

答案 26 :(得分:0)

GNU扩展通常很有趣:

my_label:
  unsigned char *ptr = (unsigned char *)&&my_label;
  *ptr = 5; // Will it segfault?  Finding out is half the fun...

成员指针的语法也让我感到悲伤,更多的是因为我没有经常使用它,而不是因为它有任何非常棘手的事情:

template<typename T, int T::* P>
function(T& t)
{
  t.*P = 5;
}

但是,真的,谁需要讨论C ++中模糊的语法?通过运算符重载,您可以创建自己的!