tags:

views:

1278

answers:

27

When have you run into syntax that might be dated, never used or just plain obfuscated that you couldn't understand for the life of you.

For example, I never knew that comma is an actual operator in C. So when I saw the code

if(Foo(), Bar())

I just about blew a gasket trying to figure out what was going on there.

I'm curious what little never-dusted corners might exist in other languages.

+6  A: 

C#'s ?? operator threw me for a loop the first time I saw it. Essentially it will return the LHS if it's non-null and the RHS if the LHS is null.

object bar = null;
object foo = bar ?? new Student();  // gets new Student()
JaredPar
@strager, yes. That's what you get for depending on SO's editor for compilation
JaredPar
That's actually quite nifty if with a totally un-obvious syntax :-).
staticsan
It's like COALESCE in SQL, very nice if you know it!
mghie
It's really cool if you stack 'em up:object foo = parameter["foo"] ?? localDefault ?? globalDefault;
James Curran
I didn't know that existed, that's really handy :)
Sophia
like python's `or`
kaizer.se
+7  A: 

This is stupid and common, but this syntax:

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

Has caught me about three times in the past year in a couple of different languages. I really like the R language's convention of using <- for assignment, like this:

x <- y

If the x = y syntax were made to mean x == y, and x <- y to mean assignment, my brain would make a smoother transition to and from math and programming.

James Thompson
Modern compilers have a warning for cases where = is an assignment expression and == is a comparison operator. You're right though, it's unfortunate that = is commonly used to indicate destructive assignment. Pascal had a better idea with :=.
Greg Hewgill
<- would be a hell to type, involving two keys in widely different location on the keyboard and one needs shift-key... Considering something that is so often used, <- is really no good for ergonomics reason
polyglot
Are you being sarcastic poly?
Whaledawg
This is one reason Icon uses := for assignment. The other is so that = can be for numerical comparison (== is string comparison).
staticsan
Using the assignment, increment, and decrement operators can be irresponsible, but they're still fun for quick hacks.I'd be happier with := if it were more aesthetic. Sadly, in most monotype fonts, the dots and lines are at different heights. Still, that's no reason to discredit it.
Nikhil Chelliah
@Whaledawg: If using a non-English keyboard this may indeed be the case. German keyboard here, '-' is left of the right Shift key, '<' is left of the right Shift key, '>' is Shift '<'. It's much worse with curly and angle braces, though. Much better to use an English keyboard for programming.
mghie
BTW, I have the following in my .vimrc file:hi DangerOps ctermbg=red:hi DangerOps ctermfg=yellow:call matchadd("DangerOps", " = ")to point this one out to me, because I've been nabbed by it as well.
Whaledawg
Many languages that use = and == make it illegal to make that mistake. If I get used to that and switch back to (say from Python to C), I find I make that mistake a lot more often.
quark
Another common solution is to follow a coding standard where you put non-assignable expressions on the left side, so that (e.g.) "`if (1 = x)`" won't even compile.
outis
+2  A: 

I was once very confused by some C++ code that declared a reference to a local variable, but never used it. Something like

MyLock &foo;

(Cut me some slack on the syntax, I haven't done C++ in nearly 8 years)

Taking that seemingly unused variable out made the program start dying in obscure ways seemingly unrelated to this "unused" variable. So I did some digging, and found out that the default ctor for that class grabbed a thread lock, and the dtor released it. This variable was guarding the code against simultaneous updates without seemingly doing anything.

Paul Tomblin
That line of code you wrote is illegal (AFAIK). Do you mean he depended on RAII, writing just "MyLock foo;" ?
strager
Super-nasty bug!
James Thompson
That's RAII, a very common idiom, but I guess programmers that have never seen it before might think we (C++ programmers) are crazy. Not that we aren't ;)
Robert Gould
Nasty "bug", but I love this style of locking. A great example of the importance of good variable and class names.
Ryan Graham
Personally, I would prefer something like this: MyLock fooLock( I agree it's a great mechanism, but it's not apparent sometimes (as in this case).
strager
Sorry for nitpicking, but this is not really a syntax issue...
itsadok
+9  A: 

C++

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

The declaration of bar is VERY difficult to see. More commonly found in C, but especially annoying in C++.

strager
cfront 2.0 used to issue a warning about this
anon
As does my compiler.
Joshua
As do I in code review.
Adam Hawes
+19  A: 

C++'s syntax for a default constructor on a local variable. At first I wrote the following.

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

This lead me to about an hour of reading through a cryptic C++ error message. Eventually a non-C++ newbie dropped by, laughed and pointed out my mistake.

Student student;
JaredPar
Gah! I hate this! One of the inconsistencies in C++ I keep tripping up on.
strager
HA! Yeah I've spent a few hours on that one myself.
Whaledawg
This IS pure evil, and its easy to forget
Robert Gould
Actually C++ is very consistent in this area - the rule is "If it can in any way be seen as a declaration, then its a declaration"
anon
@zabzonk, Hmm? It's inconsistent with new, as well as with ctors with parameters: Student *student = new Student(); // () is required (or at least allowed -- not sure).
strager
@strager - but that'can't be seen as a declaration, as the grammer doesn't allow a decl after a new.
anon
@strager - It's inconsistent with C#! hehe. 8-)
Alex Baranosky
The first is not an error, it's declaring a function which has takes no parameters and returns a Student object. That syntax goes back to C.
James Curran
@Gordon: C# is inconsistent with C++!
1800 INFORMATION
http://yosefk.com/c++fqa/ctors.html#fqa-10.19
Adam Rosenfield
+8  A: 

I was shocked Python's quasi-ternary operator wasn't a syntax error the first time I saw it:

X if Y else Z
Jason Baker
I've seen X and Y or Z. More confusing because it's not a true ternary operator...
strager
True, but python's non-typical and and or usage is fairly well documented. This isn't.
Jason Baker
The main intention of Python is to make code more readable and, while this construct is surprising at first, it is more readable.
Aaron Digulla
I still find it confusing, as it changes if-then-else to then-if-else. At least the C-style `?:` operator preserves that order.
larsmans
+5  A: 

C/C++'s bitvector syntax. The worst part about this is trying to google for it simply based on the syntax.

struct C {
  unsigned int v1 : 12;
  unsigned int v2 : 1;
};
JaredPar
Let's include the fact that the standard says you must specify signed or unsigned explicitly here.
Joshua
Missing semicolon, too. =]
strager
@Joshua, strager The SO text editor compiler is weak.
JaredPar
I was reacently tricket by the fact that internal order in a bitfield is not guarantied...
c0m4
Jared - Google for "bit fields".
quark
@notwithstanding but when you first ese this how do you know it's a bitfield?
JaredPar
+1  A: 

Iif(condition, expression, expression) is a function call, not an operator.

Both sides of the conditional are ALWAYS evaluated.

Joshua
Can you elaborate in your second comment? When using ||, only one is evaluated if the left one is zero.
strager
VB.NET's Iif doesn't work that way.
Joshua
+10  A: 

Perl's syntax caused me a bad day a while ago:

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

Without proper warnings (which are unavailable on the platform I was using), this creates a one-element hash with a key as the given hash reference and value undef. Note the subtle use of {}, which creates a new hash reference, and not (), which is an array used to populate the %table hash.

Greg Hewgill
I think you could field several hundred answers to this question with Perl.
JaredPar
Perl's syntax always gives me a bad day.
Steve Rowe
So far it's Perl, Python, C# and Powershell at one each, with C and C++ being the only one with multiple syntax gotchas. It'll be interesting to see how many Perl *does* end up with: DWIMminess means never having to say "wth" :-)
Gaurav
+14  A: 

When using the System.DirectoryServices name space to bind to an ADAM (Active Directory Application Mode; now called AD LDS, I think), I lost an entire day trying to debug this simple code:


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

When I ran the code, I kept getting a COMException with error 0x80005000, which helpfully mapped to "Unknown error."

I could use the login and password and bind to the port via ADSI Edit. But this simple line of code didn't work. Bizarre firewall permission? Something screwed in configuration? Some COM object not registered correctly? Why on earth wasn't it working?

The answer? It's LDAP://, not ldap://.

And this is why we drink.

Nicholas Piasecki
Ahh memories. No longer in X500 land but your code sent me back.
johnc
Active Directory and LDAP - bringing mainframe complexity to your desktops!
Michael Stum
+3  A: 

Powershell's function calling semantics

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

foo (5, "name")

For the non powershellers out there. This will work but not how you expect it to. It actually creates an array and passes it as the first argument. The second argument has no explicit value. The correct version is

foo 5 "name"
JaredPar
I find Powershell almost unusable because of this syntax for calling functions.
LanceSc
+4  A: 

The first time I saw a function pointer in C++ I was confused. Worse, because the syntax has no key words, it was really hard to look up. What exactly does one type into a search engine for this?

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

I ended up having to ask the local C++ guru what it was.

Steve Rowe
isn't it "typedef int (*Foo)(float, char, char);"
FryGuy
@FryGuy: not sure how you mean, but no, there's no requirement to introduce an alias for the type, which is what typedef does.
unwind
True. Usually it's done as "typedef int (*foo_t)(float, char, char);", and then "foo_t bar;", at least, in my experience.
FryGuy
+17  A: 

This is always jarring:

std::vector <std::vector <int> >
                              ^
                              mandatory space.
Paul Beckingham
Thankfully that is now fixed in most compilers. It drove me crazy
JaredPar
OH that's good to know - I'm still doing it.
Paul Beckingham
It has finally become legal in c++0x.
tstenner
+1  A: 

PHP's ternary operator associates left to right. This caused me much anguish one day when I was learning PHP. For the previous 10 years I had been programming in C/C++ in which the ternary operator associates right to left.

I am still a little curious as to why the designers of PHP chose to do that when, in many other respects, the syntax of PHP matches that C/C++ fairly closely.

EDIT: nowadays I only work with PHP under duress.

leed25d
This was 1 of the ?? reasons I stopped using PHP (and consider it an inferior language as such). +1
wuputah
I always fully parenthesize the ternary operator.
Joshua
+1  A: 

Syntax like this in C++ with /clr enabled. Trying to create a Managed Dictionary object in C++.

gcroot<Dictionary<System::String^, MyObj^>^> m_myObjs;
Aamir
+3  A: 

VB's (yeah yeah, I have to use it) "And" keyword - as in:

If Object IsNot Nothing And Object.Property  Then

See that Object.Property reference, after I've made sure the object isn't NULL? Well, VB's "And" keyword * does * not * block * further * evaluation and so the code will fail.

VB does have, however, another keyword - AndAlso:

If Object IsNot Nothing AndAlso Object.Property Then

That will work as you'd expect and not explode when run.

overslacked
Just terrible...how could they have thought that "And" should not short circuit???
Ed Swangren
OPTION STRICT will raise a warning on that one. Ed, And is bitwise.
Joshua
+1  A: 

It always ruines my day if I have to read/write some kind of Polish notation as used in a lot of HP calculators...

Peter
+1  A: 

Not really obscure, but whenever I code too much in one language, and go back to another, I start messing up the syntax of the latter. I always chuckle at myself when I realize that "#if" in C is not a comment (but rather something far more deadly), and that lines in Python do not need to end in a semicolon.

Andrew Szeto
+1  A: 

An oldie:

In PL/1 there are no reserved words, so you can define variables, methods, etc. with the same name as the language keywords.

This can be a valid line of code:

IF ELSE THEN IF ELSE THEN

(Where ELSE is a boolean, and IF and THEN are functions, obviously.)

teedyay
A: 

In a scripting language (Concordance Programming Language) for stand alone database software (Concordance) used for litigation document review, arrays were 0 indexed while (some) string functions were 1 indexed. I haven't touched it since.

llamaoo7
+3  A: 

Javascript: This syntax ...

for(i in someArray)

... is for looping through arrays, or so I thought. Everything worked fine until another team member dropped in MooTools, and then all my loops were broken because the for(i in ...) syntax also goes over extra methods that have been added to the array object.

too much php
A: 

This. I had my run in with it more then once.

acidzombie24
+1  A: 

While performing maintentnace on a bit of C++ code I once spotted that someone had done something like this:

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

Yes, they had a loop to add 1 to a number 10 times.

Why did it ruin my day? The perpetrator had long since left, and I was having to bug fix their module. I thought that if they were doing something like this, goodness knows what else I was going to encounter!

James Wiseman
+1  A: 

Had to translate some scientific code from old FORTRAN to C. A few things that ruined my day(s):

Punch-card indentation. The first 6 characters of every line were reserved for control characters, goto labels, comments, etc:

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

Goto-style numbering for loops (coupled with 6 space indentation):

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

    10         continue
    20         continue

Now imagine there are multiple nested loops (i.e., do 20 to do 30) which have no differentiating indentation to know what context you are in. Oh, and the terminating statements are hundreds of lines away.

Format statement, again using goto labels. The code wrote to files (helpfully referred to by numbers 1,2,etc). To write the values of a,b,c to file we had:

write (1,51) a,b,c

So this writes a,b,c to file 1 using a format statement at the line marked with label 51:

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

These format lines were hundreds of lines away from where they were called. This was complicated by the author's decision to print newlines using:

write (1,51) [nothing here]

I am reliably informed by a lecturer in the group that I got off easy.

redacted
A: 

AT&T assembler syntax >:(

This counter-intuitive, obscure syntax has ruined many of my days, for example, the simple Intel syntax assembly instruction:

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 */

translates into this in AT&T syntax

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!

More...

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 */

And one of my favorites.

It's as if they took the opcode encoding scheme and tried to incorporate it into the programming syntax (read: scale/index/base), but also tried to add a layer of abstraction on the data types, and merge that abstraction into the opcode names to cause even more confusion. I don't see how anyone can program seriously with this.

Longpoke
Joshua
I hope so. Doesn't change the fact that people program in it though.
Longpoke
+1  A: 

C's comma operator doesn't seem very obscure to me: I see it all the time, and if I hadn't, I could just look up "comma" in the index of K&R.

Now, trigraphs are another matter...

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

Wikipedia has some great examples, from the genuinely confusing:

// Will the next line be executed????????????????/
a++;

to the bizarrely valid:

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

And don't even get me started on digraphs. I would be surprised if there's somebody here who can fully explain C's digraphs from memory. Quick, what digraphs does C have, and how do they differ from trigraphs in parsing?

Ken
A: 

GNU extensions are often fun:

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

The syntax for member pointers also causes me grief, more because I don't use it often enough than because there's anything really tricky about it:

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

But, really, who needs to discuss the obscure syntax in C++? With operator overloading, you can invent your own!

Tom