PDA

View Full Version : C/C++ vs. Java vs. C#


Wowbagger
14th July 2009, 09:53 AM
Here is a thread for discussing the merits of various computer languages. I am starting this as an attempt to continue a discussion I was having with a fellow TAM member, that was cut off much too soon. I hope she joins us, but if not, at least I should have someone else to argue with, about these things.

Here are my thoughts, to start with:

C++ was basically the C language, with object-oriented stuff shoe-horned into it. And, as a relatively low-level language, it is still useful for developing applications where performance matters most. As a side effect of its age, though, almost all other modern language features have to continue getting shoe-horned into it, rendering it rather unwieldy to write for. Especially when they are all added in rather inconsistent ways. Writing COM components is like pulling teeth, and managed classes are sometimes even worse.

Java was a substantial improvement over C/C++ in that regard: Everything was implemented consistently (for the most part), and modern features were included from the ground up. It used syntax and semantics very similar to C++, so that older programmers could get into it, right away. However, it has a history of being a performance sloth, and it originally missed out on a few important, classic features, (such as structs). Though, much of that changed over the years (some of it inspired by C#, when it was released). One of its huge selling points is the compile-once, run anywhere attitude, which I can appreciate.

C# (pronounced C-Sharp) is an elegant language contender. Like Java, it has all of the important modern features of computer languages built into it, from the ground up. But, since it is newer than Java, it was able to be constructed with a bit more hindsight. The .NET Framework provides a one-stop-shop for almost all of your standard API needs. And, for what it's worth: its IDE (Visual Studio) is the best, most productive one in the world, as far as I can tell. It's a bummer that it is only officially supported for Windows, though.

I happen to use C# the most (when I am not stuck with VB). But, perhaps that is mostly due to historic accident. I have always been a Microsoft-platform developer, in my professional career, and I suppose there is little chance of that changing, any time soon.

What do you think?

Denver
14th July 2009, 10:02 AM
Sort of a side note: sometimes the available IDE also should be part of the equation when comparing languages. While a language itself may be more burdensome than another when actually trying to implement and maintain a system, IDE features can make up for that, and even give it an advantage over another choice.

But, a little more on target to the OP, I also tend not to give the resource-hog criteria quite the weight I did at the beginning. All things being equal, I'd rather use a language that was, for instance, more CPU intensive now, if it means easier portability and maintenance over time. Plus, depending what I mean by 'over time', the program may automatically get faster as the cpu is upgraded, whereas complex code will not get simpler over time. But ok, that may be more of a coding issue than a language one.

So anyways... I need to go back and read the OP.

tomwaits
14th July 2009, 10:08 AM
We used a book in my high school programming class called "C++ for You++".

tuoni
14th July 2009, 10:18 AM
In my view, the language you choose for a program is heavily influenced by what you're developing it to do. Most of my day-to-day stuff tends to be done in C#, but if I'm writing a website I'd actually use PHP rather than C# (with an ASP.NET front-end) unless that's what's required of me by whichever client is paying me for my code.

I must admit, I don't really give much weight to the resource intensiveness of a language since nowadays computers are (by and large) powerful enough to mostly mitigate that problem. Add to that decent garbage collection in the newer languages and I think nowadays the language one uses is (in most cases) a moot point. I would, obviously, have a completely different viewpoint if I was programming for different devices or for different situations.

roger
14th July 2009, 10:29 AM
Well, I mostly adore C++, for the reasons others criticize it. Bjarne's book on how and why he designed C++ the way he did is very instructive for those who disparage the language. Much like in the OP, people complain that it contains a hodge podge of features. Rather than a hodge podge, he built the language over a number of years, adding features that were needed, and not adding, or removing, features that didn't add a lot. His guiding principle through all of this was empericism. Study what features use and how they use it, and then support that usage. The language, for example, is OO neutral. You can use OO if you want, and not use it if you don't. You can write functional programming (such as STL), or not. You can write very close to the metal, or you can write at a very high abstraction level. Sure, it has warts due to his desire to remain compatible with C, but all in all it works. The result is definitely a "professional" language - you need to study and work hard to become conversant in it, you need to use modern tools (a strong IDE, debugger, and runtime memory and resource leak detector. But given that, you can be amazingly productive in it. I recall a few guys at my place of work who for some reason decided they were going to rewrite an application I did using more "modern" tools. They spent the next several months fighting these tools because the high level of abstraction and reliance on prewritten APIs meant you had to do things 'their way'. One guy would spend hours on the phone to Microsoft support. He found quite a few bugs in their code in the process. But mostly he fought the tools we was working with, while extolling their virtues, and talking about how much more flexible the code would end up being. Meanwhile I turned the app into a production system, quickly added features when asked, etc. All that other work got scrapped. Dumb. I still don't understand why my boss allowed that - the guy that was hired and made the argument to do it had a high opinion of his own skills, and I think he managed to paint me as a reactionary or something, while promising a magic bullet.

If someone was only interested in programming casually, I'd definitely point them to another language. Super heavy COM work might point to using another language for the main work, sticking to C++ for some heavy duty processing.

People complain about things like pointers in C++, but then it turns out they are using them wrong. Things like pointers to functions are very useful when you are writing things like state machines and event driven models. In the normal course of things, references are far safer and easier to use and keep track of. I don't tend to use pointers often, but when I use them, I really need them. I remember fighting Ada to do some things that would be easy,and perfectly safe, to do with pointers in C or C++. It takes understanding of a feature, and when to use it. I do a lot of hardware level things, so I'm likely to be writing near pure C for device drivers, using pointers and such to handle events, state machines, etc. Then I'll be using OO to help me with interface design, and then functional programming to do STL-type algorithms to manipulate the data coming from the devices. I can do all that easily with one language, and am not forced into an OO straightjacket when it is not the right tool for the job. Do you need to be on the top of your game to write like that? Sure. But being at the top of your game means being at the top of the salary range for your career - not a bad thing, IMO, though it does make it harder to apply for a new job when they hear what you make and seem dubious that you are worth it. I do worry one day I'll end up being a 'COBOL programmer' - maintaining hopelessly outdated legacy systems, but for now I'm trying to stick with C++ for my career.

dasmiller
14th July 2009, 10:35 AM
I've spent a lot of time in both C++ and C# (and a few other languages along the way), and I've read an awful lot of the language wars on Java vs. C#.

With some effort, I'm resisting the urge to write pages and pages about the pros & cons of, say, Java's enums and C#'s Properties.

So I'll generally concur with the OP. C++ is nearly self-encrypting and encourages a lot of (IMO) bad practices. ETA: Gonna guess that Roger (post #5) has a different perspective on that.

C# and Java are extremely similar; I prefer C#.

My recommendations: Use C++ if someone makes you use C++.

Use C# if you're targeting Windows ONLY

Use Java if any other OS may get involved.

------------------------
All of that is for 'typical' medium-to-large programming projects. For low-level stuff (like drivers), use C. Bear in mind that I've never written a driver, so don't take me too seriously here. And there are programmers who I respect a lot who say that everything should be done in Lisp. I haven't spent enough time in Lisp to have a real opinion.

For smaller, quicker, less formal things, Python or Ruby.
For smaller, quicker, less formal networky things, Tcl.

Now, many kids today seem to think that, for example, C++ and Java are completely different languages. That's because they haven't seen any really different languages. Sort of like French seems really different from Spanish if all you know are French and Spanish, but learn a little Russian or Swahili, and suddenly French and Spanish look very similar. With that perspective, I'd recommend that any budding programmer should spend some time fooling around with Lisp and Forth just so they see how different things really are. And code up some routines in x86 assembly- it will give you some insights into how the computer really works.

roger
14th July 2009, 11:03 AM
So I'll generally concur with the OP. C++ is nearly self-encrypting and encourages a lot of (IMO) bad practices. ETA: Gonna guess that Roger (post #5) has a different perspective on that.Well, I wouldn't say "encourages". I definitely would say "allows". Should a irresponsible person drive a 550HP, 9" raised rock crawler on the street? Probably not. They'd tip it over in a serious corner, it makes it easy to pull shenanigans in a parking lot (who hasn't seen some idiot driving their truck over a table sized rock or something to park someplace stupid and illegal), drag race at lights, etc. In the hands of somebody who knows what the tool is for, it's perfect for it's job, and nothing else works as well. "But it's so easy to drive to fast for a corner, and the CG is so high it'll tip over!" bewails the reader. Um, ya. It's a tool for going over a house size boulder at 2mph, and perhaps drive carefully at the speed limit on public roads. Not for beginners.

If you are writing a typical GUI application that takes some user input, stores it somewhere, processes it a bit, and displays the result, there's no real need for C++ these days. OTOH, if you are trying to do something serious (control a tank or airplane, write an OpenGL or DirectX application), fold proteins, write ocean current models, etc., Skinny help you if you try to do this in JAVA or .NET. Use the right tool for the job. My job requires a swiss army knife, your's needs a folding knife, doc's needs a scapel.

Nick Bogaerts
14th July 2009, 11:09 AM
What do you think?

That of the four languages you mention, I only like C. C++ (and likewise Objective-C) has two orthogonal feature sets layered on top of one another, procedural and OO, which haven't been integrated together very well. C++ has the misfortune of neither being the simple, clear system-level programming language that C is, or possessing any of the advanced abstractions high level languages provide. Linus Torvalds summarized it quite well after a rather (in)famous rant against C++:

And if you want a fancier language, C++ is absolutely the worst one to choose. If you want real high-level, pick one that has true high-level features like garbage collection or a good system integration, rather than something that lacks both the sparseness and straightforwardness of C, and doesn't even have the high-level bindings to important concepts.
http://thread.gmane.org/gmane.comp.version-control.git/57960

Nonetheless, I think there are places where C++ is the correct choice, but it's much smaller than what it is used for, and it's not somewhere I feel particularly comfortable.

Regarding Java / C#, my dislike comes mostly from a personal bias against static typing in high-level languages. Of the two, Java has a much nicer ecosystem surrounding it, the VB/C# CLI is not a particularly judicious idea, making the languages effectively interchangeable, rather than capitalising on any strength either could have on it's own, especially compared to the way Java bytecode enables both Groovy and Clojure, two quite interesting languages so far as I can tell. Groovy I've now used on one project, with another coming up, and it's been a pleasant experience. Clojure I'm still merely toying with.

Also, the part of .NET I'm familiar with (ASP.NET) is simply ghastly. I don't know if it's true for the rest of it, but I don't have much motivation to find out.

Wowbagger
14th July 2009, 11:18 AM
Also, the part of .NET I'm familiar with (ASP.NET) is simply ghastly. I don't know if it's true for the rest of it, but I don't have much motivation to find out.
Today, I am inclined to think that ASP.NET 1.1 was rather ghastly. Have you seen the newer versions? They are substantially less ghastly, since the advent of partial classes, Master pages, generics, improved @page properties, and other things.

Christian Klippel
14th July 2009, 11:34 AM
Every language has it's application. However, personally i think that if you want to write fast applications that run cross-platform, you are best served with C++.

C/C++ is a well standardized and widely used language set. As others have said, C can get as close to the bare metal as is possible using a high-level language. Some say that C is a high-level assembler. You can inline assembly code if you really need the last percent of speed available. You can do nice OO programming with C++, and you can nicely glue all that together.

Yes, C++ may have some shortcomings, but with stuff like the Boost libraries (http://www.boost.org/) and the QT toolkit (http://www.qtsoftware.com/) you can do a hell lot of things very nicely.

Java is nice, sure. But it also is a resource-hog, and most of the time rather slow. Yes, you can compile Java code into a pure binary nowdays, and many Java-VM's can use a JIT compiler to speed up as it executes. But compiling the code takes away the benefit of Java's "run everywhere directly" approach. I mean, if you are going to compile Java, why not compile C++?

JIT compilers are nice but can introduce nasty bugs. In any case, as soon as you need something with a GUI, Java is virtually a no-go. The AWT/Swing framework may or may not work the same on different machines, it may not even be the same between different Java VM's. I have seen nasty stuff with that, like buttons/sliders working fine in one VM, but were unusable in another. Or font's, or, or, or. Also, AWT/Swing is horribly slow, because it is completely unaccelerated. Everything is done pixel-by-pixel, and in Java code for most of the stuff. Maybe that changes somedays, maybe it already started to change, dunno. Haven't used it for quite some while now.

Can't say much about C#, since i never used it. However, i'm skeptical about it. You are definitely going to depend on the good will of Microsoft. There are "free" implementations like Mono, but there is always the patent threat which may void it one day. Microsoft may decide to take royalities from programmers that commercially distribute applications written in C#, simply for using their framework/libraries. Don't get me wrong, i'm not about to bash Microsoft, i'm just sceptical because of their behavior in the past.

Greetings,

Chris

Z
14th July 2009, 11:36 AM
10 REM FORUM POST
20 OPEN THREAD "http://forums.randi.org/showthread.php?t=148152" /NP
30 PRINT "I had a huge gap in my computer interactions. I grew up programming in BASIC, with some work in CoBOL, and a little exposure to FORTRAN.

Then, I went into the military and had little time to learn much of what was going on in the computer world.

I came out, and suddenly it's Java and C++ and LISP... I'm way behind. Took the Visual Basic class at college - it's like programming for people who don't know how to program. I mean, you get in to some of the basics of a program, like For...Next loops and such, but so much of it is written for you, behind the scenes... and I'm totally lost now. I can still whip up a good program in BASIC, but I don't know now what you do to translate that into a good common language.

I've looked into the simple route - __program language of choice__ for Dummies (hey, it worked great for HTML and Flash), but there are so many language and language variants out there, that I honestly don't know where to start.

I'll be lurking on this thread to get a good idea where to start - so far, it seems like the three top contenders are C++, C#, and Java. I'm primarily interested in Windows program writing, because that's what I'm using myself... so please, carry on with the debate."
35 CLOSE THREAD
40 END

dasmiller
14th July 2009, 11:49 AM
Well, I wouldn't say "encourages". I definitely would say "allows". Should a irresponsible person drive a 550HP, 9" raised rock crawler on the street? Probably not. They'd tip it over in a serious corner, it makes it easy to pull shenanigans in a parking lot (who hasn't seen some idiot driving their truck over a table sized rock or something to park someplace stupid and illegal), drag race at lights, etc. In the hands of somebody who knows what the tool is for, it's perfect for it's job, and nothing else works as well. "But it's so easy to drive to fast for a corner, and the CG is so high it'll tip over!" bewails the reader. Um, ya. It's a tool for going over a house size boulder at 2mph, and perhaps drive carefully at the speed limit on public roads. Not for beginners.

I have some sympathy for that line of thought, but it seems to me that C/C++ include features that you should never use. That, in turn, means that things that should be compile errors become hard-to-track bugs. For example, on one occasion, I spent hours time tracking down a bug that stemmed from the fact that the function declaration in the header file used different variable names than the function's implmentation (x, y vs. y, x - d'oh!). But that's a "feature?"

If you are writing a typical GUI application that takes some user input, stores it somewhere, processes it a bit, and displays the result, there's no real need for C++ these days. OTOH, if you are trying to do something serious (control a tank or airplane, write an OpenGL or DirectX application), fold proteins, write ocean current models, etc.,.Skinny help you if you try to do this in JAVA or .NET.

I'm curious on that last one. I've done DirectX programming in C#, and I'm not clear on why it would be significantly easier (or harder, for that matter) in C++.

Use the right tool for the job. My job requires a swiss army knife, your's needs a folding knife, doc's needs a scapel.

No argument there.

dasmiller
14th July 2009, 11:52 AM
Can't say much about C#, since i never used it. However, i'm skeptical about it. You are definitely going to depend on the good will of Microsoft. There are "free" implementations like Mono, but there is always the patent threat which may void it one day. Microsoft may decide to take royalities from programmers that commercially distribute applications written in C#, simply for using their framework/libraries. Don't get me wrong, i'm not about to bash Microsoft, i'm just sceptical because of their behavior in the past.

C# is my language-of-choice for a lot of things, but I definitely share your misgivings.

dasmiller
14th July 2009, 11:56 AM
I'll be lurking on this thread to get a good idea where to start - so far, it seems like the three top contenders are C++, C#, and Java. I'm primarily interested in Windows program writing, because that's what I'm using myself... so please, carry on with the debate."


If you're just doing Windows, the Microsoft Express editions of C++ and C# have good IDEs without any fiddling around to get the various pieces assembled and playing nicely; I haven't had that experience with Java yet. And if you're used to the VB IDE, the C++ and C# IDEs should look very familiar.

Z
14th July 2009, 12:03 PM
If you're just doing Windows, the Microsoft Express editions of C++ and C# have good IDEs without any fiddling around to get the various pieces assembled and playing nicely; I haven't had that experience with Java yet. And if you're used to the VB IDE, the C++ and C# IDEs should look very familiar.

That's fairly encouraging.

I guess one of my problems with computing today - much like my problem with website building - is that so much of it is done for me that I feel like I really don't know what I'm doing, exactly. I know it's much more complex than it was in the days when you POKE'd and PEEK'd your memory addresses, and that it's probably a lot nicer to have all those DATA elements pre-done for you... but it's still weird to me to just slap the elements together, write a few pieces of code to tie it all up, and claim I programmed it.

I'll still open NotePad and write web pages by hand sometimes, and then go in to Expressions Web or Dreamweaver and tweak them up a bit; but I'm so far behind the curve on programming I can't really do that with programs any more. I'm re-learning How It's Done Today, but what I really need is some way to fill in the gap from writing graphics programs on Apple II GS and video games on C-128s to the stuff done today...

OTOH, it's easy to make applications in just a few minutes. One thing I can't figure out - what are the usual methods for randomization? I remember in BASIC we had a way to do it that looked something like:

A = INT(RND(1)*100)+1

that would produce a random integer from 1 to 100 - how on earth do we do that now?

Well... back to lurk for me.

Christian Klippel
14th July 2009, 12:08 PM
Hello dasmiller,

For example, on one occasion, I spent hours time tracking down a bug that stemmed from the fact that the function declaration in the header file used different variable names than the function's implmentation (x, y vs. y, x - d'oh!). But that's a "feature?"

may i ask you what compiler you used? Because i never ever had that problem. What matters in the declaration is that the type(s) of the argument(s) match the implementation. The names are completely irrelevant usually. I know that _some_ compilers can generate, if instructed to do so, empty implementations of a function if there is no implementation given in the source, but only the declaration.

If you really had that bug because of only the names, i would tend to say that this is a severe bug in the compiler instead.

On a sidenote, you don't need to give any variable names in the declaration at all. Something like "int myfunc(int, int);" should be enough.

Greetings,

Chris

laca
14th July 2009, 12:13 PM
Well, I mostly adore C++, for the reasons others criticize it. Bjarne's book on how and why he designed C++ the way he did is very instructive for those who disparage the language. Much like in the OP, people complain that it contains a hodge podge of features. Rather than a hodge podge, he built the language over a number of years, adding features that were needed, and not adding, or removing, features that didn't add a lot. His guiding principle through all of this was empericism. Study what features use and how they use it, and then support that usage. The language, for example, is OO neutral. You can use OO if you want, and not use it if you don't. You can write functional programming (such as STL), or not. You can write very close to the metal, or you can write at a very high abstraction level. Sure, it has warts due to his desire to remain compatible with C, but all in all it works. The result is definitely a "professional" language - you need to study and work hard to become conversant in it, you need to use modern tools (a strong IDE, debugger, and runtime memory and resource leak detector. But given that, you can be amazingly productive in it. I recall a few guys at my place of work who for some reason decided they were going to rewrite an application I did using more "modern" tools. They spent the next several months fighting these tools because the high level of abstraction and reliance on prewritten APIs meant you had to do things 'their way'. One guy would spend hours on the phone to Microsoft support. He found quite a few bugs in their code in the process. But mostly he fought the tools we was working with, while extolling their virtues, and talking about how much more flexible the code would end up being. Meanwhile I turned the app into a production system, quickly added features when asked, etc. All that other work got scrapped. Dumb. I still don't understand why my boss allowed that - the guy that was hired and made the argument to do it had a high opinion of his own skills, and I think he managed to paint me as a reactionary or something, while promising a magic bullet.

If someone was only interested in programming casually, I'd definitely point them to another language. Super heavy COM work might point to using another language for the main work, sticking to C++ for some heavy duty processing.

People complain about things like pointers in C++, but then it turns out they are using them wrong. Things like pointers to functions are very useful when you are writing things like state machines and event driven models. In the normal course of things, references are far safer and easier to use and keep track of. I don't tend to use pointers often, but when I use them, I really need them. I remember fighting Ada to do some things that would be easy,and perfectly safe, to do with pointers in C or C++. It takes understanding of a feature, and when to use it. I do a lot of hardware level things, so I'm likely to be writing near pure C for device drivers, using pointers and such to handle events, state machines, etc. Then I'll be using OO to help me with interface design, and then functional programming to do STL-type algorithms to manipulate the data coming from the devices. I can do all that easily with one language, and am not forced into an OO straightjacket when it is not the right tool for the job. Do you need to be on the top of your game to write like that? Sure. But being at the top of your game means being at the top of the salary range for your career - not a bad thing, IMO, though it does make it harder to apply for a new job when they hear what you make and seem dubious that you are worth it. I do worry one day I'll end up being a 'COBOL programmer' - maintaining hopelessly outdated legacy systems, but for now I'm trying to stick with C++ for my career.

QFT. Exactly my toughts on this. Of course, much more eloquently than I could ever put it. Thank you, roger.

I love C/C++ because it does what I tell it to do, however braindead it may be (and it usually isn't :D). Doesn't get in the middle. Of course, it is also very hard to beat performance-wise in most applications.

dasmiller
14th July 2009, 12:15 PM
That's fairly encouraging.

I guess one of my problems with computing today - much like my problem with website building - is that so much of it is done for me that I feel like I really don't know what I'm doing, exactly. I know it's much more complex than it was in the days when you POKE'd and PEEK'd your memory addresses, and that it's probably a lot nicer to have all those DATA elements pre-done for you... but it's still weird to me to just slap the elements together, write a few pieces of code to tie it all up, and claim I programmed it.

Ahhh - I remember turning down the volume with POKE 53281, 64 (or was it 53280? one was pitch, the other was volume).

(some snipping)

OTOH, it's easy to make applications in just a few minutes. One thing I can't figure out - what are the usual methods for randomization? I remember in BASIC we had a way to do it that looked something like:

A = INT(RND(1)*100)+1

that would produce a random integer from 1 to 100 - how on earth do we do that now?

Well... back to lurk for me.

C# and Java each have a Random class for just that sort of thing. C++ has rand, which (IIRC) works something like that RND function you mentioned.

Christian Klippel
14th July 2009, 12:17 PM
Hello Z,

One thing I can't figure out - what are the usual methods for randomization? I remember in BASIC we had a way to do it that looked something like:

A = INT(RND(1)*100)+1

that would produce a random integer from 1 to 100 - how on earth do we do that now?

Well... back to lurk for me.

in plain C that would be

A = (rand() % 100) + 1;

to get a value between 1 and 100 (both inclusive). I think your example has a bug, it would give you numbers from 1 to 101 (101 in the case that RND(1) returns 1).

However, in C you also need to seed the random number generator using something like:

srand(time(NULL));

Instead of time(NULL) you can use a fixed value instead, if you need reproducible streams of random numbers upon each startup.

Greetings,

Chris

Edit: in case you wonder, % is the modulo operator. It gives you the remainder of a division. So, 136 % 100 = 36, 593 % 100 = 93, etc...

roger
14th July 2009, 12:20 PM
I'm curious on that last one. I've done DirectX programming in C#, and I'm not clear on why it would be significantly easier (or harder, for that matter) in C++. Okay, I'm probably wrong on that. I wrote a OpenGL program in straight C++, and then my boss wanted to see if we could switch to a commercial product that used Java, all kinds of third party libraries, all on top of OpenGL. As you might imagine, they had huge performance issues - I'd pop up and start running in a second or two, they'd take a minute to two minutes. And they were hamstrung, having no way to tune all the compenents they were using. But that is more an issue of using third party libraries, not the language. I stand corrected.

laca
14th July 2009, 12:25 PM
Hello Z,



in plain C that would be

A = (rand() % 100) + 1;


Yes, that would get a random number between 1 and 100 inclusive. What it won't do is give equal probability to each.

roger
14th July 2009, 12:29 PM
Hello dasmiller,



may i ask you what compiler you used? Because i never ever had that problem. What matters in the declaration is that the type(s) of the argument(s) match the implementation. The names are completely irrelevant usually. I know that _some_ compilers can generate, if instructed to do so, empty implementations of a function if there is no implementation given in the source, but only the declaration.si think what he was saying was along the lines of:



int secondsfromminutes(int minutes, int seconds);

int secondsfromminutes(int seconds, int minutes)
{
return (minutes*60) + seconds ;
}
The declaration and implementation assume a different order of variables.

it's an unfortunate side effect of c compatibility. There are plenty more 'gotchas' in there. OTOH, I can't really recall getting caught by many gotchas. Typical industrial strength programming practices (asserts, unit testings, stepping through all new code you write, etc) pretty much catch that stuff. But yes, it's a weakness of the language.

Z
14th July 2009, 12:30 PM
Hello Z,



in plain C that would be

A = (rand() % 100) + 1;

to get a value between 1 and 100 (both inclusive). I think your example has a bug, it would give you numbers from 1 to 101 (101 in the case that RND(1) returns 1).

In BASIC - at least the versions I used - the INT(RND) function returned a number from 0.00 to 0.99. Multiplying by 100 gives 0 to 99; hence, you had to add the +1 at the end.

However, in C you also need to seed the random number generator using something like:

srand(time(NULL));

Instead of time(NULL) you can use a fixed value instead, if you need reproducible streams of random numbers upon each startup.

Why did we have to start seeding random number generators, anyway? I don't recall, but I thought at least the Commodore took a random seed of the internal clock... I've never quite understood why we have more complex methods now than we did back in the '70s. Like declaring variables in the first place - Oh, I can see it's useful when you specifically want certain variable types, but we just went ahead back in the day and used whatever variables we wanted without declaring them.

And we walked uphill both ways, through ten miles of snow, sleet, and blistering desert heat to get to the computer store... :D

Edit: in case you wonder, % is the modulo operator. It gives you the remainder of a division. So, 136 % 100 = 36, 593 % 100 = 93, etc...

Fascinating.

Molinaro
14th July 2009, 12:30 PM
OTOH, it's easy to make applications in just a few minutes. One thing I can't figure out - what are the usual methods for randomization? I remember in BASIC we had a way to do it that looked something like:

A = INT(RND(1)*100)+1

that would produce a random integer from 1 to 100 - how on earth do we do that now?

Well... back to lurk for me.

In C#

private int RandomNumber(int min, int max) {
Random random = new Random();
return random.Next(min, max);
}

With that function declared, you would get a random number in a desired range via:

aParticularRandomNumber = RandomNumber(1, 100)

dahduh
14th July 2009, 12:31 PM
Well, I mostly adore C++, for the reasons others criticize it. Bjarne's book on how and why he designed C++ the way he did is very instructive for those who disparage the language...
I think Roger nails it. I programmed C++ for many years and used both Stroustrup's book and annotated reference extensively. Then I took a close look at Java and C#, and that's when I realized what a fantastic job Stroustrup did designing the language. Some of the things in C++ look weird or obscure when you first encounter them, but they are the product of years and years of careful thought, and their virtues are glaringly obvious when you look at another language.

Example: why doesn't C++ have garbage collection? For a couple of very good reasons. Firstly, you don't need it! If you adhere to the creation-is-resource-acquisition and destruction-is-resource-release paradigm, and you use stack-based constructors for resource management, you just can't go wrong. Secondly, with garbage collection you can't control exactly when a resource gets released. Thirdly, garbage collection is just very, very inefficient. Fourthly, garbage collection is complicated by mutual references. And so on. Java and C# designers just didn't think through all the implications, and consequently it is difficult to write inherently efficient and well managed code in either of those languages.

C++ is nearly self-encrypting and encourages a lot of (IMO) bad practices. ETA: Gonna guess that Roger (post #5) has a different perspective on that.
My experience was that bad C++ code was the product of bad programming, not bad language design. C++ is admittedly a very difficult language to master, but well worth the effort. One of the most powerful features of the language is the STL (standard template library), and if you use and extend its patterns you will never see a pointer or even see 'new' and 'delete'. With correct factorization of responsibilities it is possible to write very hierarchical code in which complexity at any given level is close to zero.

That of the four languages you mention, I only like C. C++ (and likewise Objective-C) has two orthogonal feature sets layered on top of one another, procedural and OO, which haven't been integrated together very well. C++ has the misfortune of neither being the simple, clear system-level programming language that C is, or possessing any of the advanced abstractions high level languages provide.
I couldn't disagree more. As pointed out by Roger, the ability to span from low-level to very abstract is C++'s great strength. For example, C# is wonderful if you are creating a GUI. But try to manage data efficiently and you are screwed. .NET did introduce templates in version 3 (a belated recognition of a serious omission), but by comparison to the STL its containers suck.

Regarding Torvalds' dislike of C++, I think he just never read Stroustrup's annotated reference early enough. A lot of the C code written for Linux reads like C++ with a 'this' pointer explicitly coded by hand, and the absence of stack-based destructors makes exception handling a huge pain. It's a great pity C++ was not adopted whole-heartedly, but at the time he was developing Linux C++ was still teething so it was perhaps a justifiable call.

So in answer to the OP, if you are creating a serious application use C++, but make sure all of your programmers are well trained and have read Stroustrup's annotated reference. If you are slapping together a lightweight GUI app with low maintenance requirements I suppose C# is ok, but only because it is so easy to interface to .Net and COM. Java is good for keeping you awake. But at the end of the day, its the quality of the programmer that's most important.

Molinaro
14th July 2009, 12:32 PM
i think what he was saying was along the lines of:



int secondsfromminutes(int minutes, int seconds);

int secondsfromminutes(int seconds, int minutes)
{
return (minutes*60) + seconds ;
}


The declaration and implementation assume a different order of variables.

And what he is saying is that there's no reason to code it as above. Instead you should code:



int secondsfromminutes(int , int);

int secondsfromminutes(int seconds, int minutes)
{
return (minutes*60) + seconds ;
}

Z
14th July 2009, 12:33 PM
In C#..

private int RandomNumber(int min, int max) {
Random random = new Random();
return random.Next(min, max);
}

With that function declared, you would get a random number in a desired range via:

aParticularRandomNumber = RandomNumber(1, 100)

... wow.

The technology has advanced, and computers can do more than ever before... but to get a random number, we have to type all that rather than the old way... Shouldn't it get easier, rather than harder?

Of course, I'm still having trouble wrapping my head around using variable names that are actually names (makes debugging a HELL of a lot easier though) rather than just single or double characters....

Molinaro
14th July 2009, 12:36 PM
My experience was that bad C++ code was the product of bad programming, not bad language design.

That's been my experience. Bad programmers do bad things wherever the language allows. Good programmers don't.

I don't mean to be flippant or shrug off any responsibility the language design bears towards ensuring good code, however I do feel most of the blame lies with the programmer when things go bad.

aggle-rithm
14th July 2009, 12:41 PM
When you're doing bit-fiddling with binary files, it's got to be C++. Using a language that hides pointers in that situation is like threading a needle wearing boxing gloves.

jsiv
14th July 2009, 12:45 PM
Okay, I'm probably wrong on that. I wrote a OpenGL program in straight C++, and then my boss wanted to see if we could switch to a commercial product that used Java, all kinds of third party libraries, all on top of OpenGL. As you might imagine, they had huge performance issues - I'd pop up and start running in a second or two, they'd take a minute to two minutes. And they were hamstrung, having no way to tune all the compenents they were using. But that is more an issue of using third party libraries, not the language. I stand corrected.
You're not really wrong. There are performance issues, not necessarily to the extent you're describing, but it can still be as much as 20%.

In fact, Microsoft discontinued the .NET classes for Direct3D years ago because the people who care about direct access to D3D tend to also care about performance and can't live with the .NET limitations, while the rest didn't really need it anyway and can just settle for the more abstract interfaces like WPF or XNA.

The technology has advanced, and computers can do more than ever before... but to get a random number, we have to type all that rather than the old way... Shouldn't it get easier, rather than harder?
Well, the auto-completion features of Visual Studio are excellent (and context-sensitive), so you don't actually have to type that much.

When you're doing bit-fiddling with binary files, it's got to be C++. Using a language that hides pointers in that situation is like threading a needle wearing boxing gloves.
If you want to do that kind of stuff though, you still have the option of separating that component out into native code and simply calling it from your .NET/Java application. That's done all the time.

dasmiller
14th July 2009, 12:50 PM
Hello dasmiller,

may i ask you what compiler you used? Because i never ever had that problem. What matters in the declaration is that the type(s) of the argument(s) match the implementation. The names are completely irrelevant usually. I know that _some_ compilers can generate, if instructed to do so, empty implementations of a function if there is no implementation given in the source, but only the declaration.

If you really had that bug because of only the names, i would tend to say that this is a severe bug in the compiler instead.

Oh, I think the compiler was working just fine. The types were the same, but by allowing different param names in the header vs. the body, the function looked different to the outside world.

It was many years ago - Visual Studio 1.5 or so. The problem, as I recall, was something like:

buggyfunction.h
function ArcTan2(double x, double y): double

buggyfunction.cpp
function ArcTan2(double y, double x): double
{
// a bunch of code here
}

So the bug was that the routines that called ArcTan2 weren't getting the answer that they expected.

Yes, my bad for switching the names - but if I'm trying to write code that's easy to maintain, why would I ever want the declaration names to be different from the implementation names? I'm intending that as a rhetorical question, but there may be a real answer.

Anyway, since then, I really try to work the parameter order into the function name if I have multiple params with the same type. In a case like that, I'd call it "ArcTan2YX" or some such, although I'm guessing that the standard C++ libraries have a 2-argument arctangent function and of course I'd use that rather than rolling my own.


On a sidenote, you don't need to give any variable names in the declaration at all. Something like "int myfunc(int, int);" should be enough.


When there's only one argument, and it's obvious what the argument should represent (say, Sqrt, for example) then the name isn't terribly important. But if it's possible to guess wrong about what the arguments are, or what order they go in, then there should be names there to help the poor sot who's trying to maintain the code 5 years later. Sure, that's what comments are for, but in my (limited) experience, the guys (it's always the guys . . . ) who take a lot of hard-to-maintain shortcuts are also the ones with really thin comments.

And then they get grumpy when you complain the lack of comments, and they'll give you helpful comments like:

function InitializeThing(double, pointer, double, int, pointer, int, double): void; // initializes a Thing.

Okay, I'm digressing a bit.

YMMV. A lot of people with far more coding experience than I have weighed in on both sides of these things.

Richard Masters
14th July 2009, 12:56 PM
...
I happen to use C# the most (when I am not stuck with VB). But, perhaps that is mostly due to historic accident. I have always been a Microsoft-platform developer, in my professional career, and I suppose there is little chance of that changing, any time soon.

What do you think?

I hope it stays that way. I like C#, though C and C++ are important for some high-performance applications. You can use pointers in C#, however.

Molinaro
14th July 2009, 01:03 PM
When you're doing bit-fiddling with binary files, it's got to be C++. Using a language that hides pointers in that situation is like threading a needle wearing boxing gloves.

That reminds me of a project I did as an assignment in University. I decided to make a compression algorithm of my own.

My goal was to make it compress well, with no concern for the time it takes to compress.

So, I scanned the file tabulating the frequency of all single byte characters.

The compressed file would then be built as follows:

1) Header: 3 byte string "KEN", since I called it kenpression, and my name is Ken.

2) Table: 256 bytes, of values 0-255, each occuring once, ordered from that tabulated as highest frequency, to lowest frequency in the file to compress.

3) Compressed data, with each piece being a variable length piece of data. The first 3 bits defines the length, and the subsequent bits being the data.


Data Length Number of Codes Codes
0 1 000
1 2 0010 and 0011
2 4 01000, 01001, 01010 and 01011
.
.


When I tested it, it seemed to compress most everything down to about 60% of it's original size. This was a short 3 day assignment, and I didn't do any testing on pathological data, or include any pre-compression with a RLE algorithm or anything like that.

My point being, I can't imagine how you would pack those variable bit length pieces of data, and extract them out to 8 bit bytes later, without a language like C/C++ to work with.

dahduh
14th July 2009, 01:09 PM
In C#

private int RandomNumber(int min, int max) {
Random random = new Random();
return random.Next(min, max);
}


This is how you would print 100 random numbers in C++ :D

generate_n(ostream_iterator<double>(cout, "\n"), 100, rand);

roger
14th July 2009, 01:15 PM
And what he is saying is that there's no reason to code it as above. Instead you should code:



int secondsfromminutes(int , int);

int secondsfromminutes(int seconds, int minutes)
{
return (minutes*60) + seconds ;
}
That changes nothing. If the caller thinks the order is minutes/seconds, and the implementer thinks the order is seconds/minutes, you still have the same problem.

I also very,very strongly disagree with the 'should' in your post. I think that is a terrible practice. For several reasons. With which I will now bore you with :)

Declarations are often all you get to see with commercial code where source code is not provided. Declarations should be extremely readable. To me, readable means sufficient, but no more than necessary comments.

How many times have you bought some commercial library, opened up the .h file, and seen:

int function1 (int, float, int);
int function2 (int, int, int);
int function3(int, ....)

(assume 'function' is replaced with a meaningful name)

How on earth do you use these functions? Who can tell? No comments, no variable names, etc. On the other hand:

Seconds TimeSinceMidnight (int hour, int minutes, int seconds)

is much more readable, and doesn't require much in the way of comments or printed documentation.

Of course I'd suggest using classes rather than built in types. Built in types are likely to cause problems - it's not robust programming by any means. In that case we'd have

Seconds TimeSinceMidnight (HMS thetime);

where HMS is a hours/minutes/seconds class. This example would perhaps be more obvious with dates, where europeans and americans order month and day differently.

I've seen so much code where programmers just write a minimal declaration, then put a very descriptive paragraph long comment in front of the implementation. This is horrible practice, IMO. First, we should be striving for reusable code. I don't mean code that you can plug into another application, I mean realizing that code will be used, and maintained, for decases. Each time you force a programmer to open a .cpp file to figure out how something works, you are increasing complexity. It takes longer to find the function and readability suffers. A robust class often has several related methods. Take the HMS class I alluded to earlier. you can imagine it probably has several functions to extract various values from it (hours, minutes), several other functions to assign values to it, and then more functions to manipulate it (add, subtract, etc). page, page, page, through the cpp file to figure that out, or just look at a concise header file and you'll understand 90% of the class and how to use it. For example (I'm typing this ad hoc, there will be mistakes:

// ~10 lines of instructions for class usage goes here
class HMS
{
private:
HMS ();
public:
// assignment functions
friend HMS AssignHMS (int hours, int minutes, int seconds);
friend HMS Seconds (int seconds);
... and a few more


// arithmetic operators
HMS operator+ (const HMS& time);
... etc
};
You can look at that, and pretty much figure out how to use it, all without opening a cpp file. Studies show that if you have to look at more than one screenful of code to understand something, comprehension falls rapidly, and errors multiply.

This is why I hate languages like Java - declaration and implementation all mixed together in one file. Page, page, page, just to try to discover what the class does. Not to mention this style hamstrings serious efforts at making compiling faster. When you have a million lines, compilation time maters.

Plus, the cpp files are where the programming goes on. You should only be looking at that to fix a bug. If you have to read the cpp file just to figure out what a function does, the programmer failed, seriously failed, at commenting or documenting the code. Your refusal to write 5 minutes of comments just cost each programmer 10 minutes (minimum) digging through your code. Ever tried to figure out a modestly sized program (say, 10000 lines) with bad comments, where you have to read code to figure things out? That's several days of work, easy. So, comments and variable naming in headers to explain what is done, and then commments in the cpp file to explain how and why. If you sell your code, and retain your IP, you pretty much have to do it this way anyway; why not remain consistant when the result is so readable and useful anyway?

Anyway, the way C++ does things is well thought out, but it does require discipline and knowledge. Stroustrup expected code to be written as I did it above. Fail to do that and you'll run into the issue complained about. An unfortunate side effect of the C legacy. IIRC, Ada forced the names to be the same - no bugs that way.

Incidentally, I really enjoyed how Ada had you call functions - it made code more readable. I can't remember my Ada anymore, but in C it would look like:

HANDLE CreateButton (int color, int width, int height);

HANDLE h = CreateButton (color => red, width=>50, height=>20);


edit: my perception comes from writing industrial strength code where lives are at stake. First cancer research, then aircraft flight computers, then flight planners and 3D black box playback software, and now autonomous weapons systems. You don't make mistakes in this kind of code, and you write defensively and robustly, fully expecting the code to be around for decades. I still use every day code I wrote 15 years ago, in completely different applications. (things like great circle math, speed/distance/time calculations, that kind of jazz). Once you get used to programming that way, you program everything that way, even through away GUI applications. With some obvious exceptions, what works for difficult problems works for easy ones, for the same reasons. I'll admit I'll through the occasional int around in some quick and dirty stuff I write, but a lot of that is forced anyway when you work with the Windows API, where WORD and stuff is the order of the day. Anything not GUI tends to eschew built in types.

Wowbagger
14th July 2009, 01:30 PM
In C#

private int RandomNumber(int min, int max) {
Random random = new Random();
return random.Next(min, max);
}

With that function declared, you would get a random number in a desired range via:

aParticularRandomNumber = RandomNumber(1, 100)

Just one correction needed, (which is something that always bugged me): The first parameter of the Next function is inclusive, and the second one is exclusive. That means your example will only give you a random number from 1 to 99.

You can correct for that, by pre-incrementing the second parameter:


private int RandomNumber(int min, int max) {
Random random = new Random();
return random.Next(min, ++max);
}


(Note: the ++ in front of the max.)

You can also enhance the randomness by initializing the random object with clock ticks, like this:

Random random = new Random((int)DateTime.Now.Ticks & int.MaxValue);

Nick Bogaerts
14th July 2009, 01:31 PM
Today, I am inclined to think that ASP.NET 1.1 was rather ghastly. Have you seen the newer versions? They are substantially less ghastly, since the advent of partial classes, Master pages, generics, improved @page properties, and other things.

Yes, I'm talking 2.0 and/or 3.5 here. It's not that there's anything glaringly and obviously wrong with the overall design, it's just that as soon as I get into the details I always get caught out by some random and unexplainable misfeature.

For instance, try adding optgroup tags to asp DropDownList and tell me how you get on. Or adding classes to radio buttons and/o checkboxes without having it wrapped in a span you never asked for or wanted, with the class stuck to the span. Or having an asp: RadioButtonList not generate a table element that's going to make any screen reader choke. Or making an asp:LinkButton work without Javascript. Or, for complete hilarity, put asp:RadioButtons inside a Repeater, and try to make them all part of the same group.

Unfortunately, web accessibility is my bread and butter, and as a framework, the sheer amount of things which simply don't work make ASP.NET so completely unreliable it's a struggle every day just to make websites comply with the Disability Discrimination Act to the client's satisfaction. It has neither the power and control-freakery that I get from using naked Perl or PHP, nor the convenience of using a modern web app framework such as Ruby On Rails.

dasmiller
14th July 2009, 01:32 PM
Example: why doesn't C++ have garbage collection? For a couple of very good reasons. Firstly, you don't need it! If you adhere to the creation-is-resource-acquisition and destruction-is-resource-release paradigm, and you use stack-based constructors for resource management, you just can't go wrong. Secondly, with garbage collection you can't control exactly when a resource gets released. Thirdly, garbage collection is just very, very inefficient. Fourthly, garbage collection is complicated by mutual references. And so on. Java and C# designers just didn't think through all the implications, and consequently it is difficult to write inherently efficient and well managed code in either of those languages.

Garbage collection is a trade-off. If your app is constantly creating & destroying thousands of little objects, then C#'s garbage collection could certainly cause problems. If you've got a more stable population of objects, then garbage collection can help you avoid some messy bugs. True, if you'd coded it up properly, the bugs wouldn't be there in the first place, but the garbage collector is less likely to make those sorts of mistakes than I am.

So I'd argue that garbage collection doesn't make it more difficult to have well-managed code (mutual references can be a real headache with non-garbage-collected languages, too). But I certainly agree on the efficiency part.

As for whether the C# and Java designers didn't think through the implications of garbage collection, C# was architected by Anders Hejlsberg, and he was very familiar with the Java practice when he started on C#.


My experience was that bad C++ code was the product of bad programming, not bad language design.

Well, certainly, bad code is a result of bad programming, and no language is so good that it will keep a bad programmer from making bad code. But there's something to be said for a language that nudges a bad programmer to do things less badly, or tolerates some poor code. And even good programmers have bad days.


But at the end of the day, its the quality of the programmer that's most important.

Absolutely. A great programmer with a mediocre language & environment is much more productive than an average programmer with a great language & environment.

And enormously more productive than a huge team of average programmers with a few mediocre team leads working to a schedule developed by a marketing group.

Christian Klippel
14th July 2009, 01:34 PM
In BASIC - at least the versions I used - the INT(RND) function returned a number from 0.00 to 0.99. Multiplying by 100 gives 0 to 99; hence, you had to add the +1 at the end.

Ahh, didn't know that. My Basic experience is obviously older than the data retention time of my brain :D

Why did we have to start seeding random number generators, anyway?

Well, "back then" we didn't care much about encryption, key-exchange, challenge-response methods, and the like. Also, we did not do much video or image editing on computers anyway.

Imagine you want to contact another machine somewhat securely. So you use an encrypted channel. You also use random numbers in the encryption algorithm. Now, both sides have to start at the same place in the random sequence to make it work. So, you seed the RNG first.

Another example: Imagine you want to render noise or something else depending on random numbers into video footage. You have 10 machines that can render different parts of the frame each, all at the same time. Here, again, you want to have all machines have the same random number sequence, so you seed it.

Greetings,

Chris

dasmiller
14th July 2009, 01:43 PM
Why did we have to start seeding random number generators, anyway?

I've found it very useful when testing/debugging. Suppose you're testing a game, and it crashes after a minute or two. There may have been thousands of random number calls that got it to that point, and if you run the code again, it's unlikely to ever get to exactly the same condition.

But suppose that you had seeded the random number generator with, say, 14. Now, if you run the code again and seed with 14 again, it will go through exactly the same sequence of random numbers and go to exactly the same point that crashed before.

ETA: what Chris Klippel said.

Christian Klippel
14th July 2009, 01:47 PM
And what he is saying is that there's no reason to code it as above. Instead you should code:

No. i did not say that anyone _should_ code that way.

I said one doesn't need to give names, and given an example that shows how that should look. Maybe i wasn't really clear about that. If so, my fault. Keep in mind that english isn't my first language, me being a Kraut ;)

Said that, indeed i fully agree with what roger said:

I think that is a terrible practice. For several reasons.

Instead i wanted to point out that the compiler itself should never, ever, care about the _names_ you give in the declaration vs. the _names_ you use in the implementation. The only thing that should matter is the _order_ of the arguments.

If, however, the compiler really borks up when the names are swapped/changed, then it really is a compiler bug, IMHO.

And yes, the naming should indeed be consistent between declaration and implementation.

I fully agree that it should be obvious by looking at the declaration in the header file what a given function takes as arguments. Code should be self-explanatory as much as possible. And yes, no sense in writing one line of declaration preceded by 20 lines of "documentation".

Whoever came up with the idea that you should write the code docu into the code should be punished with reading such code and explaining it for at least 5 years. Doxygen is nice to get an initial draft for source-code documentation, but way too many people overuse it.

Sorry for the derail into finer details of coding, instead of staying on-rail as to the differencies/merrits between the languages in the OP

Greetings,

Chris

Nick Bogaerts
14th July 2009, 02:01 PM
Well, "back then" we didn't care much about encryption, key-exchange, challenge-response methods, and the like. Also, we did not do much video or image editing on computers anyway.

Actually, we did. Or you did, I wasn't around back in the good old days(TM). But there's a scary amount of literature dating to quite a while back about the ins and outs of random number generators and pseudo-random number generators.

This ties in quite well to the overall discussion as well. Sometimes, you don't care wether your RNG is cryptographically secure, you don't care if it has a normal distribution, you just want it to spit out different values. This is fundamental to the UNIX philosophy, actually - simplicity over correctness.

And sometimes, you do. Sometimes, you want to make sure you're getting your numbers from your /dev/random bit bucket on Linux, not your Yarrow algorithm BSD /dev/random. But then, you'll have to expect more complexity. That's why we have different tools for different problems (again, a UNIX principle - do one thing only and do it well), not one all-purpose programming language.

Of course, everything is possible with just a hammer, goodwill, and a bigger hammer. So long as you're driving a Landy.

Molinaro
14th July 2009, 02:05 PM
I also very,very strongly disagree with the 'should' in your post. I think that is a terrible practice. For several reasons. With which I will now bore you with :)

Declarations are often all you get to see with commercial code where source code is not provided. Declarations should be extremely readable. To me, readable means sufficient, but no more than necessary comments.

I sat looking at the word should befre hitting submit on that post. I decided to leave it for the more interesting conversation is was likely to spawn.

Sad to say, you can't bore me with code talk. :o

Idealy, I don't want to look at a header. I look at the document in hand that defines whatever's in the header.

If I don't have one, and will be spending a week+ dealing with something, I'll make the document, hopefully in a few hours. Then use it thereafter. That document should exist and be up to date for any significant piece of code.

I like a naked header with a fully doc'd block in front of the implementation and a document in hand that summarizes the comment blocks.

Molinaro
14th July 2009, 02:16 PM
No. i did not say that anyone _should_ code that way.

I said one doesn't need to give names, and given an example that shows how that should look. Maybe i wasn't really clear about that. If so, my fault. Keep in mind that english isn't my first language, me being a Kraut ;)


I certainly didn't intend any words in mouth action here. I was speaking for myself, although I certainly didn't word it that way on either end of my sentance. ;)

roger
14th July 2009, 02:23 PM
Idealy, I don't want to look at a header. I look at the document in hand that defines whatever's in the header.I guess that's partly a philosophical issue, and partly a question of how your brain works.

Me, I can remember pretty much functions,and what they do. And I hate printed documentation, and electronic documentation just a bit less, for use while coding. When I wanted to learn OpenGL, for example, I read the Reference Guide and the User's guide (the blue and red books) cover to cover several times. I can't imagine trying to lean OpenGL via API documentation. At the end of that I know I can call, say, Vertex3d, and the like, and what they do. But, what are the parameters to some of these things, and in what order? My brain is such that I'll never remember. I remember big picture stuff, but details escape me. I think a lot of programmers excel at remembering details, and thus a function like int foo (int, int, int) is perfectly readable. Me, i'm scratching my head! So, your method requires me to constantly be turning pages in a book, or searching in online documentation, having several windows open, refering back and forth, just to get the parameters to a function call right. (edit: not to mention the ability to just cut and paste from the header, and then just overtype the parameters with the variables/values you want).

On the other hand, in Visual Studio, if foo is declared Seconds foo (int distance, int speed), as soon as I type 'foo (' a little ballon pops up showing me that the first parameter is distance, not just 'int'. It also shows me the return type is Seconds. But even without that feature, having a being able to refer to a header file makes it easy for me to remember function names and parameter order with the mininum of fuss and page flipping. That equals not just speed, but accuracy. Moving eyes back and forth from book page to screen increases the odds of getting something wrong.

But all that depends on my coding style. I hate the Windows API, where a simply named function like CreateFile can do things like: create a file, create a socket, create memory (memory mapped files with no physical file), etc. It does a dozen things. No one could reasonably use that without written documentation. To me that is horrible design, though there is a pretty good book out there describing how some of this came to be. In my world a function does one thing, and you generally don't use parameters to control 15 different modes. The way OpenGL handles state based programming is much better to my point of view, even if it is more verbose than the Microsoft way of handling things. 10 function calls to set the state, vs 10 parameters in a single function, all with multiple interpretations depending on what the other parameters are set to. You want documentation for all your code, and I want my code so singular in purpose that only the big picture stuff needs documentation at all.

To bring this back to language (sorry wowbagger), C++ allows you to code things like this how you want - you aren't forced into a specific mode of expression. This is incredibly important in large programs where it usually makes sense to express yourself in several different modes (OO for GUI, functional for algorithmic work, templates for generic programming, etc). But to do so without creating a mess, style becomes incredibly important. It's not just style, it's about communicating to later coders exactly what you were thinking. If the language lets you hang yourself with parameter ordering, your style better make it hard to make a mistake, and take advantage of whatever IDE tools you have (like Visual Studio's autocomplete).

Nick Bogaerts
14th July 2009, 02:31 PM
It's a great pity C++ was not adopted whole-heartedly, but at the time he was developing Linux C++ was still teething so it was perhaps a justifiable call.

That was a discussion regarding not the Linux kernel, but git - started in 2005.

roger
14th July 2009, 02:46 PM
I know these questions will never be resolved, but I wonder how much of the cause of this is people not trying to use the language as intended. For example, I love lisp, but wouldn't use it in my work, and anyone who tried to use it like C would be very, very unhappy. I used to be an Ada programmer, but switched to C++ due to the job. At first I tried to use C++ like Ada, and I was very unhappy with the language. For me the turning point was I was developing a library of heuristic algorithms in both Ada and C++. While Ada has generics, they are severly restricted compared to C++. The restrictions are there to 'protect you'. You can make an unholy mess with templates in C++; it's harder to do so in Ada. OTOH, C++ allows expressing things you just cannot in Ada. Try making a vector class in Ada that accepts int, floats, and structs. You can't (well, Ada83, I haven't used the newer Adas). That protects you if you wrote the code to only work with integer types, but if you are smart enough to handle multiple types, you can create enormously useful things. Ada thinks it should protect you from yourself, C++ thinks you should be professional enough to decide what the limits should be. In any case, I stopped using C++ as a bastard version of Ada, and recognized that C++'s design was for a reason. Type safety has advantages and limitations. Pick your poison according to your needs. In any case, even today you can read articles in the Ada literature extolling how much safer it is, using craptackular C/C++ as a point of comparison. In my experience, I write equally safe Ada and C++ (where safe to means human critical applications - bad code equals somebody gets hurt). A dumbass writing naive and "hacky" code would probably generate safer Ada than C++.

So, I spurn Java somewhat, but then I've never really used it super seriously for what it is intended for.

rsaavedra
14th July 2009, 02:52 PM
Interesting thread, though haven't had the chance to read all posts. Will post this link to the TIOBE Programming Community Index for anyone who might not know about it, or for those who might know and might want to comment:

http://www.tiobe.com/index.php/content/paperinfo/tpci/index.html

roger
14th July 2009, 03:16 PM
I had another (not original) thought - translation vs fluency. In natural languages, for awhile while you are learning you think of what you want to say, then translate it to the language you are trying to learn. After awhile, you start thinking in the language - you are no longer translating. I often see what seems like a similar thing in a lot of code I see. Not so much, say, translating C to Java (though you will certainly see that), but more translating what the person is thinking about the problem they are trying to solve into the language they are using. I consider C++ a native language to me - just as native as English, if not more so. I think in C++ (when programming). I get the sense that that is probably a bit overstated, but I think you'll see what I mean if you don't take it too too literally. To make a tortured analogy, English allows you to create horrendous sentence structures, but on average we speak grammatically and clearly based on our socioeconomic status. Esperanto and other invented languages are far superior than most natural languages as far as logic and avoiding pitfalls go, yet a fluent speaker really doesn't encounter the problems the language inventors worry about. run/ran vs going/went only trips up the learner. pointers vs references, functional vs OO, etc., only trips up the learner of C++. In any case, what I'm trying to say is I don't think in some kind of pseudocode or something when I'm designing, only to tortuously try to express it in C++. My design documents are mostly C++, with a small number of diagrams and words thrown in. It's how I think about a problem, for better and for worse (worse: a language limits you to thinking about things that are easy to express in that language.) it's hard to express in words, but I think most intense coders know exactly what I mean.

It's a tortured comparison, I wouldn't push it too far, but I think it sums up how I feel when somebody starts talking about all the troubles C++ has. I just don't encounter those problems, and I wonder what the fuss is about. Heck, I still use GOTO very occasionally (it's great when writing device handlers, and you are deep inside a bunch of conditional statements. It's even better when you write code generators, as I sometimes do). If you are fluent, a lot of the supposed problems disappear. English has the 'problem' of double negative, but all but an Aspie-type literalist will understand the statement "I ain't got no money to give you!" C++ has the 'problem' of pointers and unchecked casts, a problem that never materializes if you use them appropriately, and use other features of the language intended to avoid the real problems of pointers and unchecked casts.

Christian Klippel
14th July 2009, 03:36 PM
Roger,

well said. Pretty much the same here when i'm coding something.

Greetings,

Chris

P.S.: Do you think you could make smaller paragraphs? It's sometimes hard to read such almost-wall-of-text's. Just saying.

roger
14th July 2009, 03:50 PM
P.S.: Do you think you could make smaller paragraphs? It's sometimes hard to read such almost-wall-of-text's. Just saying.Good observation.

dasmiller
14th July 2009, 03:54 PM
I had another (not original) thought - translation vs fluency. In natural languages, for awhile while you are learning you think of what you want to say, then translate it to the language you are trying to learn. After awhile, you start thinking in the language - you are no longer translating. I often see what seems like a similar thing in a lot of code I see. Not so much, say, translating C to Java (though you will certainly see that), but more translating what the person is thinking about the problem they are trying to solve into the language they are using. I consider C++ a native language to me - just as native as English, if not more so. I think in C++ (when programming). I get the sense that that is probably a bit overstated . . .

Actually, I don't think you're overstating it a bit. Once I'm comfortable in a programming language (and the identity of that language has occasionally changed - Fortran IV, Commodore Basic, Basica, Turbo Pascal, C++, Delphi, C#. I've learned many others - PL/C, Algol, Lisp, Forth, Python, tcl, etc - without getting fluent), I really do think in it. And when I'm trying to learn a new language, at first I'm just trying to find the LanguageY syntax for doing a thing I formerly did in LanguageX. At first I don't really use the 'new' LanguageY features, and I wind up with some pretty tortured constructs to get LanguageY to do things like I did 'em in LanguageX. But after a while, I let go of X and start programming in Y the way Y was meant to be programmed.

But this leads to a lot of angry debates - for instance, Java programmers don't see the point in C#'s properties, since the properties don't do anything that you can't do with getters/setters and the Java programmers were planning to write getters/setters anyway. C# programmers think properties give a quick, clean solution without a bunch of pretty mindless getter/setter routines. The Java programmers are correct if you think in Java; the C# programmers are correct if you think in C#.

When transitioning between languages, I have occasionally found that I really was having problems that I wasn't aware of. I'd thought I had my C++ header file dependencies ("what's the big deal?") all sorted out until I started working in Delphi. I'd thought that my Delphi UI stuff was working just fine until I learned C#. I'd thought that C# handled lists just fine until I learned Python. Etc etc.

Of course, that whole "didn't know what I was missing" applies *way* beyond the field of programming.

BTW - back to the angry debates thing - I really would like to observe that I don't think I've ever seen a C++/C#/Java discussion thread that stayed this civil.

Kewl.

Christian Klippel
14th July 2009, 04:11 PM
BTW - back to the angry debates thing - I really would like to observe that I don't think I've ever seen a C++/C#/Java discussion thread that stayed this civil.

Kewl.

Just a guess, but i think it may have to do with the fact that on this board, the majority of people is used to rational and critical thinking, instead of pushing agendas of whatever kind.

After all, there is no "only wrong / only right" thing when it comes to computing. The choice of language not only depends on the language, but also on the intended application. There are loads of highly specialized languages that surely fill the very special corner in which they are used. And they do so very well.

In the end it simply matters what you want to achieve and what your overarching goals are. Want something that runs just everywhere, albeit maybe slow? Go for Java. Want perfect integration into a Microsoft environment? Go for .NET. Want to be fast and crossplatform? Go for C/C++.

As long as you know how to use a given tool or language properly, it really doesn't matter much. You can cause havoc in any language, nothing really protects you from that. Even if said havoc is just unreadable, hard to maintain code.

Arguing about "the best programming language" is as useless as arguing about the best operating system. Different people, different tastes. As long as it does the job adequately, it should be fine.

However, and this is my personal point of view, i much prefer open-source wherever possible. That goes for compilers as well as for the OS and used file formats. But again, whatever tool suits your need, use it.

As long as it doesn't involve Forth ... ;)

Greetings,

Chris

asmodean
14th July 2009, 06:02 PM
Hello dasmiller,



may i ask you what compiler you used? Because i never ever had that problem. What matters in the declaration is that the type(s) of the argument(s) match the implementation. The names are completely irrelevant usually. I know that _some_ compilers can generate, if instructed to do so, empty implementations of a function if there is no implementation given in the source, but only the declaration.

If you really had that bug because of only the names, i would tend to say that this is a severe bug in the compiler instead.

On a sidenote, you don't need to give any variable names in the declaration at all. Something like "int myfunc(int, int);" should be enough.

Greetings,

Chris

I'm not dasmiller, but I think the problem is that the args in the declaration is (x,y) but is switched in the definition. When someone looks in the header to see in what order to pass their args, they see (x,y) but the code will actually "read" them in the reverse order screwing up calculations.

Sortof, f.h:
extern int foo(int x, int y);

f.c:
int foo(int y, int x)
{
set_cursor_x(x);
set_cursor_y(y);
draw_some_stuff();
}

call that function with "foo(900, 500);" on a 1200x800 screen and watch the fireworks, for free, irregardless of compiler.

I wouldn't blame the language though, I'd blame the originator of the code.

Christian Klippel
14th July 2009, 06:49 PM
Hello asmodean,

I'm not dasmiller, but I think the problem is that the args in the declaration is (x,y) but is switched in the definition. When someone looks in the header to see in what order to pass their args, they see (x,y) but the code will actually "read" them in the reverse order screwing up calculations.

Sortof, f.h:
extern int foo(int x, int y);

f.c:
int foo(int y, int x)
{
set_cursor_x(x);
set_cursor_y(y);
draw_some_stuff();
}

call that function with "foo(900, 500);" on a 1200x800 screen and watch the fireworks, for free, irregardless of compiler.

I wouldn't blame the language though, I'd blame the originator of the code.

yes, if someone feeds the arguments the wrong way because he/she assumes the declaration to be correct, that will happen.

However, as i understood it, the compiler itself mangled it up somehow. Maybe i misunderstood that it. To me it sounded as if the declaration was something like foobar(int x, int y) and the implementation was foobar(int y, int x), when called with foobar(1, 2) it would be executed as foobar(2, 1).

And that is what i mean should not happen, if it happened that way at all. Because arguments are normally passed through the stack and are position dependent, not name dependent.

But as said, i might got it wrong.

Greetings,

Chris

roger
14th July 2009, 07:08 PM
However, as i understood it, the compiler itself mangled it up somehow. Maybe i misunderstood that it. To me it sounded as if the declaration was something like foobar(int x, int y) and the implementation was foobar(int y, int x), when called with foobar(1, 2) it would be executed as foobar(2, 1).

And that is what i mean should not happen, if it happened that way at all. Because arguments are normally passed through the stack and are position dependent, not name dependent.

But as said, i might got it wrong.
You aren't thinking it through to the conclusion. In C/C++, parameters are as you say purely position dependent.

So, for example

SetScreen (int width, int height);
foo (int height, int width)
{
doit;
}

The variable names in the declaration mean *nothing*. You could declare it as:
SetScreen (int x, int y)

And then implement as
SetScreen (int width, int height)

and the compiler won't complain. The only reason for the names in the declaration is to make it readable for the human - the compiler discards the information.

So the problem is that the programmer wrote the variable names in the wrong order in the declaration compared to the implementation.
If you looked at the header, you would think the proper call should be

SetScreen (1024, 768) to set the screen to 1024x768

but the code expects

SetScreen (768, 1024)

And so madness ensues. It's not a compiler bug, it's a consequence that parameters are based on position, not names.

to make it super clear, if you had
foo (int x, float y);

you could not then write the body as
foo (float y, int x) {...}

because here you clearly changed the order int,float vs float,int.

But you sure could write
foo (int y, float x) {}

since in both cases the first parameter is int, the second float.

Molinaro
14th July 2009, 08:07 PM
I guess that's partly a philosophical issue, and partly a question of how your brain works.

Me, I can remember pretty much functions,and what they do. And I hate printed documentation, and electronic documentation just a bit less, for use while coding.

I like printed documentation so that I don't have to switch between or have multiple windows opens. I like to leave my code on screen, as close to all the time as possible. I prefer to have anything I need to refer to, in hand.

Wowbagger
14th July 2009, 10:18 PM
Whoa!!

Just chiming in to say that this thread got waaaaay more responses than I anticipated. Further responses, from me, will have to wait a little while longer.

Wowbagger
15th July 2009, 07:31 PM
As I am reading through these posts, I find little to disagree with, and to bother commenting on. The whole "each language has its use" concept is one I think we all agree on well enough, even if some of the little details and reasonings differ.

I do have more to say about ASP.NET. But, this isn't an ASP.NET thread. So, I'm not sure I should respond to that, here, or start a new one. Hmmmm.... I'll decide a little later.

RussDill
15th July 2009, 08:31 PM
I think one of the most important considerations has to do with scalability. I think that 99% of programmers never worry about nor never need to worry about scalability. This would be from both a language perspective and an algorithm perspective. For those 99% of programmers, who cares if garbage collection is inefficient. For the other 1%, if managing objects gets them from O(n^2) to O(log n), thats a big deal. Same deal with API's, most programmers don't exercise API's fully or need them to be scalable.

I think the most dangerous individual is one that determines that a large, functioning code base, needs to be rewritten in some other language in one go.

I think we all have our own language and toolkit prejudices, but unless the reasoning is that the language and/or available toolkits cannot scale for the required project, then its really just a question of what the people doing the project can use most efficiently.

I would choose C++ along with a good toolkit like boost any day over Java and/or C#. As far as operating system kernels go, I've seen the problems that can occur with creative (but still proper) interpretations of C standards by compiler writers looking to eek out a little extra performance. I shudder to think of all the issues that could occur with a modern C++ kernel. The advantage of C is that it's very predictable. Both in the code the compiler will produce, and the behavior of operators and objects.

integral
15th July 2009, 09:06 PM
I use Python (with Numpy/SciPy/Matplotlib) for damn-near everything.

But, then again, my most of my codes have a very small distribution and are internal to my work projects.

laca
16th July 2009, 12:13 AM
<snip>
C++ has the 'problem' of pointers and unchecked casts, a problem that never materializes if you use them appropriately, and use other features of the language intended to avoid the real problems of pointers and unchecked casts.

C++ also has dynamic_cast, which does type-checking at runtime. Never used it though ;)

Great posts roger, you make my posting here quite obsolete, as our thoughts are mostly the same on these matters.

lauwersw
16th July 2009, 03:03 AM
I'm not very familiar with Java, but as far as I know it offers some native threading support. I can imagine that this offers benefits in situations like on server applications.

I'm working in a division that develops some (soft) realtime telco server applications. Most of the codebase is in C++, but one newer application is written entirely in Java. This team claims much faster development cycles, but that's hard to compare directly.

One thing that struck me though was when we got to test out the newest Sun server with their 32-core T1 processor (codename Niagara). All our apps were running on quad processor UltraSparc machines before, so they are all multiprocess or multithreaded. The C++ apps got something like twice the performance compared to the old boxes. The Java app ran at least 8 times quicker. The Java team claimed this was due to the native threading that allowed them to write the application to scale well from the start. On the other hand they've had to search for a decent third-party garbage collector to avoid heavy load spikes when the standard one kicked in every once and a while.

So I'm not sure whether any language is really superior for server apps, but I'm wondering if anyone has more experience with this native threading support in comparison with C++?

laca
16th July 2009, 03:24 AM
I'm not very familiar with Java, but as far as I know it offers some native threading support. I can imagine that this offers benefits in situations like on server applications.


I imagine it does, but Java for server applications? I fold.


I'm working in a division that develops some (soft) realtime telco server applications. Most of the codebase is in C++, but one newer application is written entirely in Java. This team claims much faster development cycles, but that's hard to compare directly.

One thing that struck me though was when we got to test out the newest Sun server with their 32-core T1 processor (codename Niagara). All our apps were running on quad processor UltraSparc machines before, so they are all multiprocess or multithreaded. The C++ apps got something like twice the performance compared to the old boxes. The Java app ran at least 8 times quicker. The Java team claimed this was due to the native threading that allowed them to write the application to scale well from the start. On the other hand they've had to search for a decent third-party garbage collector to avoid heavy load spikes when the standard one kicked in every once and a while.


All I have to add to that is that the C++ apps must have been written wrong.


So I'm not sure whether any language is really superior for server apps, but I'm wondering if anyone has more experience with this native threading support in comparison with C++?

Who says C++ doesn't have native threading support? What do you mean by native?

lauwersw
16th July 2009, 03:41 AM
All I have to add to that is that the C++ apps must have been written wrong.


Probably :) Some part of the core was even written for VMS and scalability was kinda bolted on later. So the comparison is maybe not entirely fair.



Who says C++ doesn't have native threading support? What do you mean by native?

C++ threading mainly comes from the Posix API. It's workable, but you have to be careful to protect all your data with locks, avoid deadlocks and so on. If you try to apply that to some of the STL containers, you always end up writing wrapper classes, so you must always put your concurrency at a high logical level. I was wondering whether Java has improved on that in some way (or any other language)?

If not yet, I feel like native threading and support for scalable data containers could be a major benefit to any langauge. The first language to get that completely right will be a winner in the serer space. It's much more likely to end up in Java than in C++.

jsiv
16th July 2009, 04:38 AM
Er? C++ doesn't have threading, that is provided by an operating system API (or a wrapper for that). Threading is very low-level though, so unless the goal is to manually squeeze out every last cycle you can, we're really approaching a point where even lower level languages like C++ require parallelism libraries that let you abstract the dirty work away so that you can just (for instance) call parallel_foreach() and have the iteration split up into several threads and managed automatically.

ddt
16th July 2009, 04:52 AM
C++ threading mainly comes from the Posix API. It's workable, but you have to be careful to protect all your data with locks, avoid deadlocks and so on.
As jsiv noted, C++ itself has no threading. And strictly speaking, C++ cannot even have threading. The library function strtok is not re-entrant, and errno is useless too if taken literally from the standards definitions in a multi-threaded environment. I know, nitpicking, but the C-standard was not written with multi-threading in mind and C++ inherited that.


If you try to apply that to some of the STL containers, you always end up writing wrapper classes, so you must always put your concurrency at a high logical level. I was wondering whether Java has improved on that in some way (or any other language)?

If not yet, I feel like native threading and support for scalable data containers could be a major benefit to any langauge. The first language to get that completely right will be a winner in the serer space. It's much more likely to end up in Java than in C++.
The Java collections framework (the equivalent to C++'s STL) has many containers in two versions: a thread-safe version and a non-thread-safe version (HashMap versus HashTable for instance).

However, I think the need for a thread-safe collection/container is relative. When you properly design your app, you don't end up with using a bare collection, but using it inside another class anyway - which doesn't just expose all the possible methods of the collection class, but only those aspects of it you actually want to be used. For instance, when you need a stack of some objects, you only expose the pop() and push() methods.

In such a case, you don't want a thread-safe collection, you want the thread-safety on the methods of your own wrapper class.

lauwersw
16th July 2009, 04:54 AM
Er? C++ doesn't have threading, that is provided by an operating system API (or a wrapper for that). Threading is very low-level though, so unless the goal is to manually squeeze out every last cycle you can, we're really approaching a point where even lower level languages like C++ require parallelism libraries that let you abstract the dirty work away so that you can just (for instance) call parallel_foreach() and have the iteration split up into several threads and managed automatically.

Exactly what I mean in half the amount of text!

So does Java have any parallelism libraries or anything native to abstract the dirty work? Or C#?

laca
16th July 2009, 12:06 PM
Er? C++ doesn't have threading, that is provided by an operating system API (or a wrapper for that).

That is why I asked what he means by native. Native to the language or native to the OS? The language has no built-in support for threads. But it has access to, well, basically anything from the OS.

laca
16th July 2009, 12:10 PM
As jsiv noted, C++ itself has no threading. And strictly speaking, C++ cannot even have threading. The library function strtok is not re-entrant, and errno is useless too if taken literally from the standards definitions in a multi-threaded environment. I know, nitpicking, but the C-standard was not written with multi-threading in mind and C++ inherited that.


Yes, it can. Even strictly speaking. strok may not be reentrant, but strtok_r is. All library functions which were designed as not reentrant have counterparts that are. And also, there is TLS for errno and such.

jnelso99
16th July 2009, 12:23 PM
If I remember right, the upcoming C++ standard will have some threading features. Downloading the latest draft to make sure...

The Visual Studio 2010 beta may have basic support for the new standard already.

As for the OP: C? C++? Java? C#? Easy - whatever the company's code is already written in. So for me, C/C++ and Java.

Nick Bogaerts
16th July 2009, 01:28 PM
I do have more to say about ASP.NET. But, this isn't an ASP.NET thread. So, I'm not sure I should respond to that, here, or start a new one. Hmmmm.... I'll decide a little later.

A new thread would be awesome. I couldn't get bored debating this.

roger
16th July 2009, 01:37 PM
A new thread would be awesome. I couldn't get bored debating this.Didn't we just get done pointing out C++ doesn't have multi threading support?

;)

Molinaro
16th July 2009, 01:45 PM
Didn't we just get done pointing out C++ doesn't have multi threading support?

;)


I see, sharp reply.

dahduh
16th July 2009, 01:51 PM
A great programmer... ...
[I]enormously more productive than a huge team of average programmers with a few mediocre team leads..
This is something I was never able to figure out. A supercoder can be easily 20x more productive than an average programmer and churn out much cleaner code. So what's the secret, and how do you find them? I eventually gave up entirely on interviews, qualifications and experience, and just said "show me your code". The great coders whip out 100,000 lines they wrote at home and the not so great mumble something about 'proprietary'. Unfortunately when you impose this filter employment agencies stop sending you people.

I think the most dangerous individual is one that determines that a large, functioning code base, needs to be rewritten in some other language in one go.
That's how you recognize a moron.

I feel like native threading and support for scalable data containers could be a major benefit to any langauge.
There's a problem: it doesn't make sense. For example, a thread-safe implementation of STL map<> in C++ runs 100 times slower than a non-thread safe version. But most of the time you want to perform say 10 operations on a map at any one time, and usually you want to access a couple of related data structures as well. It's much more efficient to lock a mutex once, do your operations, and then release. So 99% it doesn't make sense to make containers thread-safe; it's up to the programmer. And in C++ it's foolproof:

void myfunc()
{
guard _g(mutex); // constructor of guard locks mutex
// ..do your stuff...
// ... destructor of guard release mutex, works even if exception is thrown
}

Just two rules: never make external calls with a mutex locked, and always lock multiple mutexes in the same order. This is where Windows' event queue falls down with a big soggy splat.

Nick Bogaerts
16th July 2009, 02:39 PM
I see, sharp reply.

*AWKward silence*

roger
16th July 2009, 02:48 PM
*AWKward silence*
Oh, just go FORTH and COBOL up a new thread.

Nick Bogaerts
16th July 2009, 02:59 PM
This is something I was never able to figure out. A supercoder can be easily 20x more productive than an average programmer and churn out much cleaner code. So what's the secret, and how do you find them? I eventually gave up entirely on interviews, qualifications and experience, and just said "show me your code". The great coders whip out 100,000 lines they wrote at home and the not so great mumble something about 'proprietary'.

The only reliable way I know of is to get students. If by the time they go back to Uni you panic because their hand-over notes are inadequate, you know you've found someone.

Unfortunately when you impose this filter employment agencies stop sending you people.

Does it also stop them cold-calling you? We once tried convincing Manpower we only recruited people if they (a) were foreign, (b) had funny names, but it was of no use, they just don't get hints.

Wudang
16th July 2009, 04:06 PM
Absolutely. A great programmer with a mediocre language & environment is much more productive than an average programmer with a great language & environment.

And enormously more productive than a huge team of average programmers with a few mediocre team leads working to a schedule developed by a marketing group.

Absolutely. I was in complete awe of a small team I worked with who built code that was more stable than the base it ran on (somwg which shreiked and died at a minor kernel panic and treated kill -1 as kill -9).
A very few people are like that and can transfer it. I have met many people who were fantastic on a platform that, if you know what I mean, worked the way they thought and were absolute crap on other platforms because "it shoudn't work that way". My current job is salvaging the crap one such wrote and making it work right while still processing the original stuff. I am but a programmer for the working day...

Wowbagger
16th July 2009, 05:30 PM
Anyone program for the Lego Mindstorms NXT?

Maybe we can have a debate on the merits of NXC vs. RobotC vs. leJOS

lauwersw
17th July 2009, 03:19 AM
Thanks all for the replies about threading, I'm trying to digest all that information.

It looks like native language threading (which is what I meant with native anyway) or thread-safe libraries is no holy grail, mainly because of bad performance. So it's at this point definitely not a decisive reason to choose for Java.

You can indeed hide locking nicely in C++ classes, but it get's bad for performance if you have to scale over more than a few threads in my experience. That's probably why in our software here at work concurrency is done in a number of different ways. Functionality is split over a number threaded processes that use message passing and load-balancing. I guess it will stay like that for the near future, the solution probably won't come from the programming language then.

Paul C. Anagnostopoulos
19th July 2009, 04:40 PM
It should have been called ++C rather than C++. Then it went downhill from there.

~~ Paul

Paul C. Anagnostopoulos
19th July 2009, 04:51 PM
This is something I was never able to figure out. A supercoder can be easily 20x more productive than an average programmer and churn out much cleaner code. So what's the secret, and how do you find them? I eventually gave up entirely on interviews, qualifications and experience, and just said "show me your code". The great coders whip out 100,000 lines they wrote at home and the not so great mumble something about 'proprietary'. Unfortunately when you impose this filter employment agencies stop sending you people.
There is certainly a lot of truth in this. However, I have had the displeasure of attempting to maintain code written by fabled superprogrammers and it was a nightmare. Sometimes the 100,000 lines of code is written quickly, but at the expense of the poor schmuck to follow.

A lot of it has to do with style. We had a thread awhile ago about commenting style, for example, and there was much disagreement about the best way to comment code.

Another problem I've seen has to do with how people view the structure of code. I wrote a lot of code in Bliss, which is an expression language (like Lisp). That means that everything is an expression; there are no statements that cannot be used as expressions. So what do you think of this:

x := f(y, (for i := 1; i <= n; ++i do
exit i if a[i] = 0));

Is that good code? A couple of people reamed me for coding like that. "Oh," I said, "we're not really supposed to follow the philosophy of the language, I guess."

~~ Paul

Wowbagger
19th July 2009, 06:42 PM
I once tried to create a language called !C , but then everyone started calling me a racist.

dasmiller
19th July 2009, 10:33 PM
I once tried to create a language called !C , but then everyone started calling me a racist.

Were the programmers supposed to have funny little mustaches?

dasmiller
19th July 2009, 10:47 PM
This is something I was never able to figure out. A supercoder can be easily 20x more productive than an average programmer and churn out much cleaner code. So what's the secret, and how do you find them? I eventually gave up entirely on interviews, qualifications and experience, and just said "show me your code". The great coders whip out 100,000 lines they wrote at home and the not so great mumble something about 'proprietary'. Unfortunately when you impose this filter employment agencies stop sending you people.

My experience is limited (fortunately!) - but I have a thought on the matter: An average programmer will come up with a way to make his code work. A great programmer will come up with many ways to make his code not fail.

For example, if you ask a programmer to come up with a simple routine - say, a ToUpper(char c). An average programmer will whip up a few lines - convert the char to a byte and add 32 (or subtract? whatever), for example. If you point out that this won't give the right result for numbers or letters that are already uppercase, he'll get sullen and say "well, you didn't tell me it had to handle those."

A really good programmer will say "okay, you add 32, or just binary-OR 20h, or use a lookup table, or build a little logic structure with a few 'if' statements, but - are we space limited, or speed critical, or what? And will it only be passed lower-case letters, or does it have to handle uppercase letters? And what if the calling routine sends it something that's not a letter, or isn't a printable character? Should it throw an error, or return a #32, or what?"

That's the one who's thinking through all the ways that his code might mess up the app before he/she starts typing. That's the one you want.

laca
19th July 2009, 11:59 PM
That's the one who's thinking through all the ways that his code might mess up the app before he/she starts typing. That's the one you want.

YES. Beautifully put.

roger
20th July 2009, 06:45 AM
There is certainly a lot of truth in this. However, I have had the displeasure of attempting to maintain code written by fabled superprogrammers and it was a nightmare. Sometimes the 100,000 lines of code is written quickly, but at the expense of the poor schmuck to follow.
The problem there is fabled.

Modified
21st July 2009, 12:20 AM
There is certainly a lot of truth in this. However, I have had the displeasure of attempting to maintain code written by fabled superprogrammers and it was a nightmare. Sometimes the 100,000 lines of code is written quickly, but at the expense of the poor schmuck to follow.

Manager: "We need it by next week."

Engineer: "I can do that, but it will be hard to maintain and modify, and in the long run it will cost you more than if I do it right. That will take about a month."

Manager: "Can you finish by Thursday?"

Paul C. Anagnostopoulos
21st July 2009, 04:42 AM
Manager: "Can you finish by Thursday?"

Engineer: "All righty then. I'll start coding now while you go off and write the spec."

[with apologies to Dilbert]

~~ Paul

Wudang
21st July 2009, 11:54 AM
I once replied "When you go to a restaurant do you ask the chef to start cooking and you'll tell him what you want later?"

blobru
21st July 2009, 02:59 PM
I once tried to create a language called !C , but then everyone started calling me a racist.


Careful overloading the swastika operator.