Bjarne Stroustrup Previews C++0x
Szplug writes "Bjarne Stroustrup has a sneak peek at the additions to C++ that he expects will be completed (hopefully) by 2009. Included are language-defined threads, optional garbage collection, some automatic type deduction, and template concepts. From the article: 'The list of current proposals is still quite modest and not anywhere as ambitious as I'd like. However, more proposals are being considered and more libraries will appear either as part of the C++0x standard itself or as further committee technical reports.'"
Having programmed in numerous languages I can't help wonder if it's really worth it. There's a reason why languages come and go. Bolting on new features might be more like treating the symptoms rather than the cause?
Time will tell, I guess.
.: Max Romantschuk
"C" was an unusual enough name for a language. Then "C++", which makes sense to you or I but would only mystify a non-geek. Now "C++0x"? How is that even pronounced? "See Plus Plus Zero Ecks"? Or maybe just "C...ocks"?
Names like this serve to only further mystify computing and programming among the non-geek population.
With spending like this, exactly what are "conservatives" conserving?
What I started to hate in C++/Java/C# is that there's no easy and standard-conforming way to express complex data 'inline'. Yeah, it's cleaner to make it XML and load it runtime, but there's no simple+quick way to do that either.
Hell, you can't event put known non-uniform data in C++ vector without doing it one-by-one.
fucktard is a tenderhearted description
"And C++ programming languages, we own those, have licensed them out multiple times, obviously. We have a lot of royalties coming to us from C++."
i n/0,14179,2877578,00.html
http://techupdate.zdnet.com/techupdate/stories/ma
You know where to send your royalty checks.
Thanks
Darl McBride
I think it is obvious that this guy has no idea what he is talking about when talking about C++.
By the time he's finished with C++0x\n==%d, I bet the specification will look suspiciously similar to that of Common Lisp!
Yes. Even if a better language comes along in the next few years, it will take more than three years (probably more than fifteen years) for C++ to stop being common.
Censorship is telling a man he can't have a steak just because a baby can't chew it. --Mark Twain
I also have come to realize that if there is one bad thing in C++ than it is this preprocessing which it inherited from C. Especially in a large project the trouble of including the right files and linking against the matching libraries becomes a pain in the ass. In this respect I would like C++ be more like Java (or TurboPascal for the matter) where interface declarations and compiled code are unified. At the moment moving around code from one DLL to another is a lot of work, while in my perception, it could have been completely transparent from the users point of view.
I do realize that keeping backwards compatibility was one of the design features of C++, and that it also determined the success of C. But as many C++ tools are now able to make use of precompiled headers, it seems that the problem should be able to be done away with.
If we want to write complex and secure programs quickly, we need better languages, and more features does not mean better.
You're an immobile computer, remember?
The work on C++0x has entered a decisive phase. The ISO C++ committee aims for C++0x to become C++09.
C++ octal-9???
Slashdot social media options: AIM, ICQ, Yahoo, Jabber and Mobile Text. Why no MySpace?
Translation : C++ will continue to be a highly useful language, as long as some other sucker does all the hard work
'Some other sucker' being the hundreds of C++ experts across the world who contribute to the C++ Standard Library and others (e.g. Boost). What would you prefer - Stroustrup does it all single-handed?
As the article says, C++ is a 'general-purpose programming language with a bias towards systems programming'. If the libraries were lumped in with the core language, C++ would be a much less flexible and less appropriate tool for those kind of tasks.
Take what we have now, add whatever we want, for fucking christ sake get something coherent out of it and call it C+++.
How can one add to something incoherent and get a coherent result?
How about having a slashdot interview about C++0x with Strousrup? I think it would be a good forum to gain more insights about C++ and a fine possibility to allow a community (in this case the slashdot readers) to make and to vote on feature proposals.
This has really brought out the C++ haters. Still, most commercial applications, games, utilities, OS's, etc are still written in C++ (or a combination of C and C++). There is a reason for this; it is because C++ is both incredibly effective and extremely efficient. Sure, its possible to create artificial benchmarks that prove otherwise, but in te real world where performance counts, people use C++. But when they want flexibility they go for Ruby or Python or something similar. If you want outstanding applications, you use an outstanding language like C++. If you want average applications, you use an average language like Java.
Surely that should be C+=2
But considering that lots of OSS projects like Firefox and KDE still use C++, not to mention commercial games like World of Warcraft, C++ probably does have some saving merits.
interface and implementation (both are keywords, comes from pascal) section: lets get rid of seperate header and code files. The idea is aged, inefficient and doesn't help clarity nor ease of coding.
Bit-arrays: yesyes, I know. Boost contains a class which does that. But I think it would be so much nicer if the language had that feature.
I doubt Google, Adobe, or many of the thousands of other companies depening on C++ will be throwing their code base away any time soon. Rather, they will want their C++ code to be more robust and more managable. The features the article lists all seem to do this.
(See Stroustrup's C++ Applications page for more.)
Tell me about it! And those fancy editor thingamajiggs? A-phoooey! Real Programmers use cat(1) and do it right the first time!
sudo ergo sum
I still think C++ was invented as a joke.
Not a joke, a research project. Thus, Stroustrup's willingness to include any "feature" that someone suggests: "Oh sure, we'll put that in and see how it works out."
The upshot is a language that is accreted instead of designed.
When I found the C language, I stopped looking. Ah well.
Too bad.
-jcr
The only title of honor that a tyrant can grant is "Enemy of the State."
In my opinion, many people are trying too hard to be clever and advanced.
I was advanced once, but unfortunately it just left me waiting for everyone else to catch up.
He who knows best knows how little he knows. - Thomas Jefferson
There'll be good money in it in a few years, when noone who graduated this century masters it, and all the non-masochists have moved on too, but stuff still needs to be maintained. The old COBOL story all over again.
sudo ergo sum
They do redefine C every few years, the last time was in 99. Of course, the changes were minor. The biggest one I remember was that // is now a comment, and a few other tweaks. No whole features added.
I still have more fans than freaks. WTF is wrong with you people?
What would you prefer - Stroustrup does it all single-handed?
It might be nice if he could.
Stroustrup lives in a fantasy world where the only reason C++ isn't as fast as C, or produce as small of assembly as C is because of the compilers- which he conveniently disavowes responsibility for.
Compare to Objective-C: You'll note that these new C++ "concepts" feature are extremely similar to Objective-C's "protocols"- only not only can a moderate programmer produce a fast Objective-C compiler, they'll know exactly where it can be slowed down and why.
It'll also already be able to do these things in C++ that are so new and innovative.
Meanwhile, some C++ compilers can make "cout << 1 << endl;" slow- and others only do it when the programmer tries to make their own "cout" like device.
If the libraries were lumped in with the core language, C++ would be a much less flexible and less appropriate tool for those kind [systems programming] of tasks.
No, it's if those libraries imposed greater responsibilities on the runtime. As it stands, the C++ runtime already has an awful lot to do- albeit less than Java or Objective-C.
Worse still: The C++ runtime isn't a peer to your own code as it is in Objective-C: With Objective-C you can interact with the runtime as if it were regular library calls.
C has a mountain of library code available, and the functionality of that library code drives new extensions to the C core language (TLS extensions, for example)
But then, C has almost zero runtime (and if you reject certain extensions: it actually has no runtime), and that's what makes it suitable for systems programming.
I don't think C++ is now, or ever was (or with the way these "extensions" keep showing up) - or ever will be suitable for Systems Programming.
Because the C++ programmer infrequently can understand what his runtime is doing- and is not encouraged to know the interface by which C++ does it's magic (because nobody knows- they're still trying to figure out how to make some C++ magic work in a way that isn't slow)- a C++ systems programmer needs a C++ runtime. Nobody has one in systems-space, so the C++ programmer (which isn't a programmer of C++) needs to write it.
The inventor of C++ can't even do this, but any moderate programmer could do this for Objective-C.
What I'd really like is a fully vertical programming environment that's more humane, lets me get to the bare metal if I want to, or be very lazy and high level, if I want to, it would do assembler, C, C++, and higher than C++ level, a set of languages where I know what each statement expands to in the lower level, where the compiler sort of holds my hand, and shows me what's going on, and I'd rather have a more plain english compiler output even if it's not optimized, or if it's optimized and difficult to follow the jumps, then a plain english description of why it's doing it. What happens when I write a statement and get a bug is too much behind the scenes for me, too much of a smoke and mirrors, too cryptic. I'm lazy and prefer writing programs the easy way, in very high level languages, say in basic, python and perl, unfortunately they lack performance because most are interpreted. There should be a way to do high level without interpretation, but instead compiling into lower level stuff, after all, instructions in one language should have a 1 to 1 matching of what happens in another language, or there could be such an optimized matching. If I was allowed to constantly inspect what each high level construct translates to in the lower level language that's still higher than assembler, in a human readable form, that could improve the overall performance and bug issues for all the levels of programming, because if there is a problem, a bug, the programmer could inspect and figure it out and submit patches. I find myself learning things mostly when I'm involved with a task at hand, if I didn't have a problem, I'd never learn about something. I'm sure most people are intelligent enough to figure things out if they really need to, but they have no transparent and easy way these days, it's all or nothing, C++ to straight assembler, and they are stuck with starting off writing a program in a difficult and low level language because that's all you can do - once you made choice and settled on a language, or even a set of libraries, you're stuck with it, and if you don't like the language code, you're welcome to look at the compiler output in assembler. I'd rather see some smoother transition layers, something that starts out very nonverbose and progressively gets more verbose and difficult as you go lower on the layers. Something that starts out as simply as drawing a few diagrams to generate some very high level code, almost in plain english, that a compiler translates into C++, that I can look at, and even see what C++ would translate into in C, and then C into assembler. Some Microchip PIC c compilers retain the original C code next to the assembler part, so it's readable what's going on. Even dotnet that's an interpreted language, that too can list the bytecode next to the original code. I'd like to see what happens, all the way to the bare metal. Yes compiling time would go up, but you could skip intermediate stages if you wanted to. One of the worst things these days is that there is no single programming environment where I can sit down and 'own' the computer, without working my ass off, unless I want to. An environment that debugs the speed of the code, shows you what happens where, what code consumes a lot of memory, what code portion took how many milliseconds to execute, and with this constant feedback, I could concentrate my efforts on the portions I'd like to concentrate on. You could have the 4 level layers called C-02, C-01, C+00, C+01, C+02, etc. C-02 equivalent to the architecture layer, C-01 to the C layer, C+00 to what currently C++ is, C+01 to something like basic or python, and C+02 to some diagramming software (like VB/VBA macro record or Visio or something similarly super-easy). You could then directly compile C+02 to C-02 if C+02 diagramming software is all you know, or go deeper in the in-between levels, depending on how much elbow-grease you'd like to put in and what your skill level is, you could go from C+02 to C+01 to C+00, each code expandable if it has a hand-coded equivalent, or just using the de
No features??? Try complex numbers, inline functions (i.e. typesafe macros) and variable declarations which does not have to follow the start of a scope and restricted pointers.
"Civis Europaeus sum!"
It's not that hard to see if there's a 'const' in the function prototype, is it?
I was pleased to notice that Bjarne Stroustrup has acknowledged that they won't be pursuing to include a GUI framework into the new C++ standard.
;)
Although this might be considered a disappointment, his citing the fact of low resources, time and money are best spent in other areas. Lets get something out the door that we can use now instead of waiting for the GUI. I'm no C++ expert, as a matter of fact I'm only into about 400 pages of my first teaching book
Nobody will deny the power of some of the C++ GUI's out there, QT is probably best of breed. Its probably good to have commerical interest in the GUI space, since the desktop is forever evolving faster than a C++ committee could handle.
When I found the C language, I stopped looking. Ah well.
Go hack mplayers source code, and then come back saying that. C++ might not be a panaeca, but danm, C code can get very, very, very ugly sometimes.
May the Maths Be with you!
>> When I found the C language, I stopped looking. Ah well.
> Too bad.
I guess I should have qualified my comment, really. I suppose in part it comes down to what problems one is trying to solve. I'm an embedded designer, working on small systems. Assembly and C turned out to be the right tools for the job. So I guess I should really have qualified my rant with "in my line of work".
The red mist has lifted now!
Open Source Drum Kit, LPLC deve board - mjhdesigns.com
C++ template concepts are no better (or worse for that matter) than C# generics constraints, they only bind differently: C++ binds to a name, C# binds to an interface. Both are equally rigid. Both require foresight. In C++ you don't have to derive your class from a specific interface, but on the other hand you still need to implement the function knowing what name it will be accessed through (i.e. should it be named begin or Begin or GetBegin).
It is good for a language to have threads "built in". As mentioned in this paper, "Threads Cannot Be Implemented as a Library": http://www.hpl.hp.com/techreports/2004/HPL-2004-20 9.pdf
if you do threads in a library, you run into problems with semantics or performance. Semantic problems == compiler breaks your multithreaded program. Performance problmes == compiler does naive translation of program, terrible performance.
http://www.thebricktestament.com/the_law/when_to_
It can get ugly, if it isn't designed.
But if you spend just a little up-front design time, it is also very easy to create nice clean code.
Refactoring C after a year of development is not that hard.
Refactoring C++ after a year of development can be impossible.
Did you say reuse? Bah.
they should call it ++C, so then the "shouldn't you iterate the language BEFORE you use it" jokes can go away.
99 bottles of beer in 175 characte
Translation : C++ will continue to be a highly useful language, as long as some other sucker does all the hard work.
Well, the power of most languages is in the libraries anyway. What is Java or C# without the standard libraries? I program in C++/Qt and rarely if ever touch all that is ugly about C++. The very few places I allocate memory myself for operation with other code I check it rigorously, Qt objects handle themselves. I use QString and QBytearray and never have issues with zero-termination or buffer overflows. Signals and slots will never crash on a dangling pointer. The new Qt4 containers with foreach are brilliant. So yeah, core C++ may be functionally poor but if you need the equivalent of java or C# it's a library away.
Kjella
Live today, because you never know what tomorrow brings
The thing is that one of C++ main design points is that it should be able to do everything a computer can do; it is a system programming language.
That is why it will always include features which will force the programmer to think whilst typing, unlike in Java (my current job) which is a lot easier but won't allow such low level access to the computer.
As for the preprocessor issue you describe; it's type-safety.
Slashdot social media options: AIM, ICQ, Yahoo, Jabber and Mobile Text. Why no MySpace?
I think you have missed, or underestimated the effects, of having to pre-define the interface rather than just using it. In C++ you just write the template code, in C# you need to have an interface defined. How many do you think get a bit lazy and use a more generic interface that includes constraints not nessesarily used in the specific function call?
- These characters were randomly selected.
Sure; let's add in closures, inline FORTRAN support and programmer mind-reading too.
When life gives you lemons, you CLONE those lemons, and make SUPER-LEMONS. -- Dr. Cinnamon Scudworth, Ph.D
At the very least, the new name could be Y2K compliant.
C++09 doesn't seem to do that. At this rate, they'll still be making updates in 2109, so maybe they should clear the ambiguity and rename it from C++0x to C++200x
http://www.mozillaquest.com/Linux03/ScoSource-02_S tory03.html
"C++ is one of the properties that SCO owns today and we frequently are approached by customers who wish to license C++ from us and we do charge for that. Those arrangements are done on a case-by-case basis with each customer and are not disclosed publicly. C++ licensing is currently part of SCO's SCOsource licensing program."
Thanks
Blake Stowell
It's the ninth-circle-of-hell compiler optimisation. It does some form of distributed computation using hell's citizens' bones for data storage and avian carriers for data transfer, and will protect your Windows box from spyware because its binaries are more evil.
> And reference variables?
There is no such thing as a reference variable, you clearly don't know the C++ language. references are not variables. references are newly defined identifiers that refer to an object that already has identifiers referencing it, they don't change, ever, hence are not variable... But I see that you *really* meant *pass* by reference, if you want to ensure that the function can have no side effects, cast the parameter to const. Otherwise, if you expect to write software without knowing what the functions do, you should not be writing software.
BTW, when you say "fancy allowing standard operators to be overloaded" I think you mean "overrided". C has overloaded operators (+ is defined for int, char, short, long, float, double, etc). overriding lets you tell the compiler how to do addition for your custom bigint library, or whatever. You can misuse operator overriding, or you can misuse macros, each are there for a purpose, and each get misused by bad programmers.
> And now garbage collection? That just a feature to fix poorly written code.
No it isn't, it is a feature to simplify the determination of object lifetime when that lifetime depends on complex (or more likely, merely chaotic) runtime factors. Bad programmers use it to fix poorly written code. Sure, every lifetime can (maybe) be determined by some complicated equation, but when you have limits on how much CPU you can use and limits on how much time you can spend on maths, you use garbage collection.
The trick is only to use garbage collection when you know that you need it and what it means. There's the problem with most dynamic languages.
cat > /vmunix
I also have come to realize that if there is one bad thing in C++ than it is this preprocessing which it inherited from C. Especially in a large project the trouble of including the right files and linking against the matching libraries becomes a pain in the ass.
/usr/local/strange_module-2.3.7 and that would pass -I /usr/local/strange_module-2.3.7/include to the preprocessor and -L /usr/local/strange_module-2.3.7/lib to the linker.
Even though headers and libraries are the most common problem I come across from day to day, it wasn't until now that I thought about it as an implementation problem.
I'm not sure about the preprocessing bit. ifdefs and includes to get prototypes and other global/module specific variables are very handy. Its just a little silly that there is not a common preprocess and link flag that you can tell your compiler to find includes and libraries. How about gcc -F
How tough would that be? You can always explicitly add linker or preprocessor flags if you need to, but I would find this method superior to the current one by far. One of the biggest issues with preprocessing and linking is the order of the search path. Having it as one flag to pass to both of preprocessor and linker would simplify things.
And if you don't "do it right"?
I think he means to call it C++x0r. Cause the type safety makes you ub4r.
The perfect sig is a lot like silence, only louder
I personally have more hope in this alternative.
To me, D has surfaced to become what I always thought C++ should have been. I hope (and believe) that it will be giving C++ more competition in the comming years. It might not be ready for full production yet (due to lack of big supporters and libraries, mostly), but I have tried it out on several of my own projects, and I love it.
It's much more interesting to me to hear about what Barne will be taking OUT of C++. Adding features is the easy, wimpy part of the job. Removing them is the part that takes cohones.
-russ
Don't piss off The Angry Economist
++ is the increment operator, C++ is C that has been incremented with new OO features (be that for better or worse is a personal opinion in the same league as religion)
I still think C++ was invented as a joke. I mean, fancy allowing standard operators to be overloaded.
C++ was well intentioned, but yes, it has turned into a bit of a joke. Operator overloading is indeed a carnival of confusion that would have been best avoided. As a Lisp programmer I chuckle at the artificial distinction between operators, functions and methods.
And reference variables? I now have to carefully examine very function prototype when I need to know if a function call might have side effects.
I don't find these to be egregious. C's pass by value is a bit idiomatic, although it is simple and works well. Use const properly to avoid side effects.
And now garbage collection? That just a feature to fix poorly written code.
Agreed. I would rather see threads in the standard library instead of GC. GC promotes sloppy programming. It appeals to legions of Java and C# programmers, the bottom feeders of the programming world.
When I found the C language, I stopped looking. Ah well.
C will always be useful because assembler will always be with us. So yes, everyone should program in C. But for even more karmic hacking I prefer Lisp.
an ill wind that blows no good
Why do they want so many years to decide on so simple things that are other languages take for granted for more than 15 years now? Let's see what they have in store:
But what makes the most negative impression is the willingness to recognize that the programming language world has made huge steps in the last few years, and C++ is light years behind. Here are some of the negative points, in random order:
...and stop all this high-level language folderall. Real Men program in raw machine language, not some namby-pamby crutch like C++.
Remember: counting in binary is just like counting in decimal...if you're missing nine fingers!
"My country, right or wrong; if right, to be kept right; and if wrong, to be set right." --Senator Carl Schurz (1872)
I've never looked at mplayer's source code, but the fact that last I looked, the default makefiles still use -O4 (a non-existing optimization level) have always made me wonder a bit about the devs. Still, ugly code and Gentoo-noob style compiler opts notwithsdanding, mplayer remains the best media player/encoder around, as far as I'm concerned. Interesting paradox.
Implementing a garbage collector for this language, even if optional, will kill it. There is a reason for C++ still not having one, it is because it is impossible to write one without restricting the language. Even if you can disable the collector, you'll can not use the constructions that it doesn't unerstand, so this C++0x wont be suitable exactly to what C++ does well.
If you want Java with native widgets, please, rewrite the widgets, not Java!
Rethinking email
Bjarn says he wants to make C++ an even better systems programming language. The way to do this is apparently by adding features to a language already groaning under the last batch, far from all of which have been consistently implemented in all (or even a majority of) compilers. None of these features seem to address the fact that as a systems programming language, C++ has most of the same shortcomings as C, while adding a few of its own:
1) It is no more portable than C. In particular, various fundamental data types are still dependent on the underlying CPU architecture for their size and format, leading to copious macro #ifdef sections in low-level code that must run on a variety of different systems.
2) Use of the extra abstraction mechanisms provided by C++ tends to result in code that is both larger and less performant. This is not a desirable attribute in a systems programming language.
3) It is already an extremely complex language that requires an extremely complex compiler to implement it. This makes it very difficult to validate, thereby rendering it useless for whole classes of systems programming tasks (e.g. high-reliability embedded systems).
4) The language is a mine-field of ambiguities, overloaded meanings, and counter-intuitive default behaviours that conspire to make it incredibly difficult to learn properly. There are so many potential pit-falls that even very experienced programmers from other languages have trouble writing high-quality code with it, meaning that the language is actually a source of problems in many projects rather than a mechanism for solving them.
It is thus not (as Bjarn claims) a "better C", at least in a systems programming context, because nearly everything it adds is largely superfluous to systems programmers, and comes at a cost that they are unwilling to pay. This is especially true in what is by far the largest segment of systems programming, i.e. embedded systems, many of which are programmed in _significantly simplified_ versions of C, not the goya-esque monster that is modern C++.
NB: it is very difficult to design a single language that is equally useful for both high-level applications programming and low-level systems programming because they have fundamentally different requirements. Systems programmers require precise control of minutiae, whereas applications programmers want something that lets them churn build quality end-user systems with a minimum of pissing around. C++ falls between these two stools, adding nothing useful to C's systems programming capabilities, while being so concerned with nit-picking minutiae that writing high-level applications in it is like scrubbing a very big floor with a very small toothbrush. It is IMO well-suited to only one notable application domain: games development, which is unusual in requiring a mixture of both low and high level code.
I'm not going to change your sheets again, Mr. Hastings.
I agree 100% - C++ is too feature-heavy as it is. Bjarne should stop while he's only a little behind ;-).
As far as the preprocessor goes, one of the things I don't like about Java is the lack of a preprocessor. Sun ended up having to build assert() into the language because of it. Yes, the preprocessor can be abused, and perhaps it needs to be redesigned, but having no preprocessor is too restrictive.
I know there is this grass-roots "D" language floating around, but I'd like to see a C+=2 (or perhaps E?) that started back with the current ISO C standard, then added object-oriented features in a more organized, well-thought-out fashion.
(And no, I don't consider C# to be the answer. C# was just Microsoft's way of cloning Java. Now Sun and Microsoft are in a pissing match with Sun playing catch-up this round, trying to force features into Mustang to catch up to C# 3.0.)
Don't underestimate the power of The Source
I can't believe someone rated you "3 interesting" for a crap post like that.
...) which is why things like templates were introduced as a first in C++ and LATER adapted in languages as Java and C#. So who's leading?
It's like judging the quality of a car by the features of the glove department. Obviously you haven't been doing any serious C++ programming to come up with this sort of comment. I suggest you try to read Andrei Alexandrescu (google that up yourself) for some real programming power.
I can't believe people can be serious about calling Java and C# more modern than C++; they don't even have multiple inheritance or class-local typedefs. Or how about switching your code to call a memberfunction at compile-time vs at runtime (as in templates vs polymorphism). How will you do that if you are forced to use a virtual machine?
Oh no wait, the next big thing: Ruby on Rails (that's Retards on Rails to me). Everybody in the industry knows the major drawbacks of code generation (generate code, change generated code, IT manager says the specs change, regenerate code, redo the initial changes, notice they don't work anymore,
You people make me tired.
And what if there's nothing behind the door until it is being opened?
0x = the year 200x, where x may equal 9. (?) I'm not sure. Just a thought.
Here are some things I personally would like to see (some of which have been mentioned elsewhere as possible inclusions). Not all of them are 100% appropriate for something like C++ and the C++ standard library but all of them are things that seem (to me) to be usefull things to have as compiler and library provided functionality.
language provided thread support. This would need to provide the following (at least):
1.Proper thread safety at the language level (including mandates that the standard library is thread safe)
2.Thread-local storage (i.e. a way to say "this variable is local to this thread")
3.A way to say "this block of code should only be accessed by one thread at once" or "this variable should only be accessed by one thread at once" (something like a critical section on win32 I guess)
Plus of course ways to create threads and such.
Complete compatibility with C99 (i.e. any valid C99 program is also a valid C++0x program and will compile and run)
something similar to (and compatible with) fstream/ifstream/ofstream except that it reads from a block of memory instead of a disk file
A nice sane cross-platform way to detect memory leaks (i.e. the compiler implements the standards-specific memory leak detection in the implementation of new and delete and then the progammer would enable it e.g. with a new #paragma or something. (this goes with the garbage collector idea mentioned elsewhere)
Complete unicode support throughout the C++ language and standard library (although I think this is already mostly there)
New classes or functions (e.g. a new string class and new/improved collection classes) designed such that they help prevent or miinimize buffer overflows and memory corruption and the resulting effects (sort of like how compiler vendors like microsoft have started to add "safe" string functions only standardized)
Standardized definitions for constants like pi (plus more math functions as standard)
A standard library to do data compression and uncompression (perhaps an implementation of what is defined in RFC 1950, RFC 1951 and RFC 1952 i.e. the algorithim and format used in gzip, pkzip and zlib would be appropriate). Further to this, a new fstream/ifstream/ofstream derivitive that will compress data when writen out and uncompress it when read back in (without the programmer having to do anything).
I like the idea for a standard library way to do directory and file manipulation and the idea for a standard sockets library although (like the compression idea I have above), I do wonder if they are really appropriate for C++ or if they are better provided by third party libraries.
I ressent your synicism.
- First they ignore you, then they laugh at you, then ???, then profit.
And using C++ template concepts - "Oh, in 2009, AC is going to need to use an int in a template that needs the CountDown member function, we better make int implement it".
Same thing, different taste. (Not that primitives have member functions in C++, but feel free to exchange int with something other.)
As far as I can see:
./ discussion were about the new features of C++0x instead of the old "C is better than C++", "python is better than C" and "x86-assembly beats the pants off both".
1) people complaining here about C++ or its will-be features either aren't C++ users or don't understand much of C++;
2) people who have at least managed to RTFA to the end are complaining about new features of the _language_, that will be _few_, while the biggest efforts will be oriented towards extending the STL, which is the really important part.
Btw, only a C user that understand C++ poorly could complain about references. If you find yourself at ease with C, by all means, use it. But don't spit on another well engineered language without the necessary knowledge to do so.
By the way, about references: what's so different when passing to a C function a pointer to a struct, instead of a reference to a C++ one? Don't you have still to read the prototype to know you must pass a pointer indeed? There's just one small difference between C and C++: guess what, if the prototype is a const reference in C++ you've more guarantees the object won't change than with a const pointer in C, since C++ enforces constness. And you don't even have to worry about pointers referencing to free'd memory.
It would also have been nice if this
Oh, well: it's Slashdot after all. What was I expecting. Sigh.
42.
As a Lisp programmer
[...]
GC promotes sloppy programming.
I cannot reconcile these two statements.
This is because the .dll file does not contain any information of .h files being used during the compilation. And I hope you can change the "effect" of an .h file by defines in other .h files. So, one would have to examine the preprocessed files to determine whether the interfaces would match. The evil of preprocessing is that you lose all kind of information that is essential for the kind of type-safety that you would like to have in an environment where you make use of libraries.
And this problem is not specific to DLL files on MS Windows, but also occurs on other platforms where shared libraries are in use and the libraries do not contain an explicit interface definition that can be validated. (And we all know that a simple version number is not sufficient for interface validation.)
it's called C++0x for now because it hasn't been finalized yet. When it's finalized, as expected in 2009, it will be C++09, just as when the last revision was finalized it was C++98
Most languages are revised over the years, deprecating some things, adding others.
Java, for example, has deprecated and added HUGE numbers of features and classes, and there've been many more official/standard versions of it than there have been of C++
Inconceivable!
While C++ is more strongly typed than C, C++ is not type safe. Type safety means that the language ensures that no operation will ever be applied to a variable of the wrong type. However, C++ supports the ability to access arbitrary memory locations, allows type casting, and automatically converts types in many instances. Java is more strongly typed than C++, as it doesn't allow access to arbitrary memory locations, but it also supports casting and automatic conversions, and so is not type safe. If you want type safety, try a language like Ocaml or SPARK Ada.
You really need to do this:
/vmunix /dev/tty
:-).
ln -s
Then you have to type in your OS on each reboot - kind of like having a 1.5 million character password
Don't underestimate the power of The Source
The problem with preprocessing is that you never can establish a reliable relation between the interface definition (.h files) and the compiled code (.exe or .dll), because the compiler does not know which .h files where used after preprocessing has taken place. And I hope you realize that the used of #defines in one .h file can change the definition of classes in another .h file. So, even in a collection of .cpp files that compile into a library or executable, it is possible to introduce "bugs" due to miss-alignment of member variables that are very hard to find. Preprocessing as it is done in C (and C++) is simply bad. But I guess that most people don't realize it, because they have become used to it.
What you say is true for C++98 templates, but C++98 templates are not the same thing as C++0x template concepts. C++98 templates grants you to use any member (function, typedef, variable, etc) of a type, but C++0x template concepts does not allow you to use any other member than those specified in the concept of a type.
No need, the Unix way is not to compicate a program with features but instead to combine another small tool with it to together achieve the functionality. There are quite a few things around that could do this for you, Make, Ant, etc or even just the shell.
DIR=/usr/local/strange_module-2.3.7
CFLAGS=$(DIR)/include
LIBS=$(DIR)/lib
Thus, Stroustrup's willingness to include any "feature" that someone suggests: "Oh sure, we'll put that in and see how it works out."
That's actually pretty libellous. You need to read "The Design and Evolution of C++" and get back to us.
Along these lines, one problem I am aware of from my C++ days is this:
The caller allocates the memory for a new object. The class code initializes the data members. This is ok if everything is compiled together.
But if you use shared libraries, and you change the class to contain more or fewer data members, you must re-compile all the calling code.
So much for data hiding.
You can work around this limitation by providing functions or factory class methods in your shared library to do all your constructing, but this is extra work.
"We can't solve problems by using the same kind of thinking we used when we created them." -- Albert Einstein
There has been a lot of talk about getting rid of C++ altogether. I can't help but think C++ will continue to be used (and with good reason) by many schools and universities. Being such a low level language, C++ does a good job at teaching one about memory and computer architecture while also teaching principles of programming. Learning C++ with help one with a computer architecture course and vice versa. It is also a nice transition language between learning a programming language and learning assembly programming. Do we really think it will be gotten rid of? Just a thought.
When Objective C has templates then maybe I'll look at it.
With C++ I can write one piece of code that can process pixels with 8 or 16 bit integer channels or 16 or 32 bit floating point channels. Fanboys of Objective C and Java are obviously not writing image processing software.
Without such important features as operator overloading, constructors, stack-based objects, and references, I really can't take Objective C seriously. I can't imagine it being used for much mission critical software, that's for sure.
You know, as excited as I am about a new C++, when I looked at some of the code Bjarne offers up as an example I have to say that I feel a bit underwhelmed.
I know all you C++ guru's out their are just IN LOVE with template classes, but you should pick your head up every now and then and look at how other languages are tackling the issue. Other languages offer the same inherent functionality in MUCH cleaner ways at the expense of a little CPU. You already have RTTI, use it, and save us all the pain of debugging a class with 4 template parameters (which themselves are probably templated classes)....
Don't even get me started on the useless error messages heavily templated code causes the compiler to emit.
td
hard core geek-ware
Actually, the correct pronunciation will be "See Plus Plus".
:-D
As soon as some buzzword-compliant HR department gets a hold of this, they're going to be sending job-reqs to dice through stupid non-tech headhunters. They'll want someone with 10 years of C++0x experience (C++ is insufficient now) and who's willing to take a retarded online test to prove it. How many times have you heard a brain-dead recruiter spell out acronyms that are usually pronounced or pronounce acronyms that are usually spelled out? I vote for Cocks. At least it's a word bimbo T&A recruiters will understand.
Disconnect your television. Do your own research. Draw your own conclusions. They're probably lying. Don't be a sheep.
Because it can't be done cleanly. It makes RTTI seem pale and benign, and that's still turned off in most projects. It breaks with all C tradition and you would basically need to include debug symbols for everything, including libraries, in your runtime code, as the point of mapping a string to an arbitrary variable is that it's arbitrary. In addition, you can easily do it over select domains of fields by preprocessor and templates, auto-registering stuff as it's run, in your own hashtable.
Lambdas! Lambdas! Lambdas! Lambdas! Lambdas! Lambdas! Lambdas! Lambdas! Lambdas! Lambdas!
Lambdas! Lambdas! Lambdas! Lambdas! Lambdas! Lambdas! Lambdas! Lambdas! Lambdas! Lambdas!
Lambdas! Lambdas! Lambdas! Lambdas! Lambdas! Lambdas! Lambdas! Lambdas! Lambdas! Lambdas!
Lambdas! Lambdas! Lambdas! Lambdas! Lambdas! Lambdas! Lambdas! Lambdas! Lambdas! Lambdas!
Lambdas! Lambdas! Lambdas! Lambdas! Lambdas! Lambdas! Lambdas! Lambdas! Lambdas! Lambdas!
It is tedious, inefficient and unclear to define a functor for single-use transformations, away from where the code is actually used.
C++ is already a multi-paradigm language.
Add some functional concepts while you're at it.
Your DLL problems are a problem of Windows, not of C++. C++ does not try (nor it should) to fix Microsoft's architecural problems. C++ just tries to be as powerful and the least intrusive it can be.
I often find that programming with C++ for Windows is mostly programming for Windows, with a ver little tiny bit of C++ thrown in to bind things together. Expanding on the reasoning on the first paragraph, it seems C++ succeeds admirably well on this.
My USD 0.02
http://www.dieblinkenlights.com
What does 0x mean? That somebody got creative?
No, it just means that Stroustroup doesn't know how long it will take the new standard to be finalized, but that he expects it to be done before 2010. '0x' is a year, and the 'x' is a placeholder for the unknown portion of that year. If you prefer regular expression format, we could call it '0[6789]'. In fact, based on the rate at which such things happen, we could probably say '0[89]'.
Note to ACs: I usually delete AC replies without reading them. If you want to talk to me, log in.
C++ is a better, superset of C. The features can be used individually without forcing you to use other ones or change programming paradigms and you do not pay for any features you do not use.
Are you sure that there are NO features in C++ that would make your life easier? For instance I can think of a few (and you can pick and choose) that drop straight into C programming with no overhead or change from C-style at all but make life much nicer:
-// comments
-better compiler warnings
-stronger type checking, no default int
-ability to define variables throughout the scope, ie for(int i=0 ; i<10;++i)
-namespaces
-overloaded functions, default arguments
Some libraries that are more efficient that what you'd write yourself:
-string vs C's char[]
-list/map/vector etc
And some new ways to think about programming:
-polymorphism/inheritance
-templates
-destructors and RAII
Sorry for rather long and muddled post, and also for my poor English... Also, if you have allergic reaction to Lisp advocacy, don't read any further.
Some years ago when I had some spare time I was struggling a lot trying to make C++ a better language. I was trying to reinvent reflection, easy serialization, extend metaprogramming facilities and so on. My hopes were mostly in http://www.boost.org/">Boost C++ libraries.
At some point I've decided to try to write some extended metaobject generator, like Qt's moc, but friendlier to "modern C++", using GCCXML. In addition to generating reflection info, I was thinking of generating proxy classes and other stuff like this.
Among other things I've tried to do some of XML translation work using XSL (i.e. XML AST from GCCXML -> some more AST convenient XML representation -> (transformation) -> resulting metaobject AST. I've discovered some interesting things about XSL, e.g. that it's possible to "emulate" iteration (which is somewhat lacking in XSL) with recursion. Nevertheless after a few days of fighting with XSL I've decided to try some language which is more suited for processing various trees. Of course, when C++0x is ready, I thought, it will be the best language in all respects, including tree stuff, but as of now, STL+boost::lambda+whatever is still somewhat quirky (for instance, look at those 10 pages long error messages when you make a typo). So, although I was heavily influenced by standard myth-based mindset concerning Lisps (slow, interpreted, purely academic, "lost in a sea of parenthesis" and so on) I've decided to give Scheme a try, as I've heard that it can be used as a better XSL.
After playing with Scheme for a while, I've found out (to my surprise) that the language can be used for many other purposes besides list (tree) processing and simple scripting (as in Gimp). As an example, there are wonderful things like Scsh. It's possible to write Web applications, many Schemes can do OO. My deep respect to C++ (The Most Powerful Language Ever) began to fade, albeit slowly.
So I've begun to try to do some real things in Scheme. Disillusionment has come rather quickly due to the fact that a lot of critical stuff in Scheme (e.g. OO and packages) is not standardized and thus is 100% non-portable between implementations. Moreover, every implementation has its bugs and limitations, and when you come to the point when you need to change your implementation you discover that most of your code needs to be rewritten from scratch.
I was nearly ready to continue developing my "metaobject generator", pushing Scheme's role back to "better XSL". But something made me try Common Lisp before doing so.
What quickly became apparent to me from my CL experience is that most of problems Boost guys are fighting against are just plain nonexistent for Lispers. Look at this, for example: variant.hpp. A good workaround for C++ typing model. What do we have in Common Lisp?
(sorry for mangled indentation)
Now look at this beauty: boost::lambda. Don't forget error messages it produces when you mistype something or stumble across a bug. CL example?
Not to mention Lisp's GC versus boost::shared_ptr.
OK, these are areas where dynamic languages like Perl, Python and Ruby, and even statically typed like C# or Java are catching up to some degree. Now let's look at some CL's more-or-less unique features.
You bring up an excellent point about the rigidity of C# generics constraints. One of the crucial features of the proposals for concepts in C++ is retroactive modeling, which allows you to adapt to the specific syntax of a concept *without* changing your data type. So the problem you mention for C# generics is not actually a problem with C++
// the type of values on the stack
concepts.
Here's an example. I'm writing a concept for a Stack, which might look like this:
template
concept Stack
{
typename value_type = S::value_type;
void push_to_top(S& s, const value_type& value);
void pop_from_top(S& s);
value_type& get_top(S& s);
bool is_empty(const S& s);
};
I picked some silly names on purpose. Now, std::stack doesn't match the syntax of this concept. So what if we try to pass a std::stack to a function like the following, which expects something that is (we use the term "models") a Stack?
template
void clear_stack(S& s)
{
while (!is_empty(s)) {
pop_from_top(s);
}
}
It's going to fail to compile, because std::stack does not match the syntax of the Stack concept. If C++ concepts had the same restrictions as C# generics in this regard, we would be stuck writing an adaptor class. Yuck.
Retroactive modeling saves the day. We can fix the problem by writing a model definition like this:
template
model Stack >
{
typedef T value_type;
void push_to_top(std::stack& s, const T& value) { s.push(value); }
void pop_from_top(std::stack& s) { s.pop(); }
value_type& get_top(std::stack& s) { return s.top(); }
bool is_empty(const std::stack& s) { return s.empty(); }
};
In this model definition, we're meeting all of the requirements of the concept by providing function definitions that transform the syntax of the Stack concept (pop_from_top, is_empty, etc.) into calls to the std::stack itself (see the function bodies). Now, when we call clear_stack() with a std::stack, it "just works": the calls to is_empty() and pop_from_top() in clear_stack() go through the model definition. Of course, if we picked more standard names and member functions in our Stack concept, the model definition could be empty or (for implicit/structural concepts) omitted entirely.
Retroactive modeling is *really* important for making it easier to reuse template code. You won't need to be paranoid about matching syntax *exactly* with every concept you need to model, because the compiler will detect any mismatches and you can fix them through a model definition---without having to change the data types, templates,
or concepts. Of course, people will still try to agree on names and concepts when possible, because it saves typing. You can check out the actual proposals before the C++ committee (references follow) for more information. There are two active proposals, but the groups are working together, so expect a final "combined" proposal in the future.
There are other differences between C# generics and C++ concepts. Before starting to design concepts for C++, most of the authors of one of the concepts proposals (N1849; see below) did an extensive study of the generics facilities of several languages (e.g., C# generics, Java generics, Haskell, ML functors, C++ templates). They ran into trouble with every language they tried, and we designed our C++ concepts to avoid those problems. Here's the original paper; there's an extended version (with more languages and more detail) under review:
Ronald Garcia, Jaakko Jarvi, Andrew Lumsdaine, Jeremy G. Siek, and Jeremiah Willcock. A Comparative Study of Language Support for Generic Programming. In Proceedings of the 2003 ACM SIGPLAN conference on Object-oriented programming, systems, languages,
Windows is like decaf - it tastes like the real thing, but it won't get you through the day.
We italians are quite creative with the english language... just another way to say that we invent new words when we don't know them off-hand. Strange enough, the word "constness" exists, and it's a perfectly legal one in English. You can even google for that! :-)
Maybe also English people invent new words when they don't exist. ;-)
42.
I like most of these additions, though I wonder why they're not just standardizing the (currently nonstandard but widely supported) STL hash containers for hash tables. Regexps are also already in the language in the form of a POSIX library (regex.h), though I don't think MSVC++ supports that, and the regex library could definitely become more user-friendly.
:)
The "auto" keyword being used to automatically determine the type of a variable sounds like it can cause no end of trouble, especially when using polymorphism (will auto give you back a pointer to the base class or the derived one? What if the function isn't virtual? etc.), so I probably won't be using it in my future programming.
Garbage collection AND dynamic allocation via new/delete together? That ought to be interesting... and probably very dangerous
The "using" thing after the template definition seems pretty useless and confuses the template declaration with potentially unrelated aliases. Why not use a typedef further down in your program?
Concepts were something I wanted to see in the language from the first day I learned about templates. They should make debugging template issues much easier. I'm glad to see that they're considering them.
(I didn't write the AC post above) You are getting silly now trying to defend your point. Please google for "duck typing".
.zero() method.
You can't add methods to primitives (in C based languages, anyway) but because of operator overloading there are still options available. In fact combining Operator overloading and templates is quite cool:
template<class T> T min(T a, T b) {
return a<b? a : b;
}
ie this would work for int, float, as well as your own matrix class (if you implemented operator<).
I once made a container that returned the average of all the objects in it (all things I hadn't made myself eg float, int, short, matrix, 2D vector etc). To do this you need to somehow reset a counter to zero, which is pretty hard if eg the matrix class can't accept an assignment constructor of 0. The solution of course is "*= 0", which works assuming that has been defined.
The only way to do that in C# would have been if someone had the foresign with all of those classes to have added a virtual
C++ is a better, superset of C.
C++ is to C as Lung Cancer is to Lung.
Also, it's not a proper superset of C.
-jcr
The only title of honor that a tyrant can grant is "Enemy of the State."
As a systems language, right now, no. But there is some really interesting-looking work on the MS Research page (the Singularity project, if I remember) with using it as that with some crazed tools they have, and exploiting the features of "safe" languages to make a different sort of system.
As for "C+=2", have you looked at Objective C? I believe that its general purpose is to provide a "better" OO implementation, although I've never used it myself. That said I think it runs all C code (where C++ does not) so possibly not all that OO from the ground level...
(gcl)* (list "Lots of Irritating Superfluous Parenthesis" "Lisp uses garbage collection, you insensitive clod!")
("Lots of Irritating Superfluous Parenthesis" "Lisp uses garbage collection, you insensitive clod!")
Get off your soapbox. Some of us like languages that actually have syntaxes and can really do low-level work.
Syntactic sugar for getters and setters can be useful for providing a more natural interface (as long as people don't abuse them), but they don't really have any place in a language like C++, where almost everything is set in stone at compile time. Properties work well in dynamic languages like JavaScript because the binding takes place at runtime, at the very last moment before the member access is resolved. The code to access a plain member field vs. a property is quite different, and in C++ this must be generated at compile time.
The upshot of this is that you can't change a field to a property and vice-versa while retaining binary compatibility. This means that you've essentially added a gotcha to the language which everyone must be wary of when designing their public interfaces. While a.b = c looks a bit prettier than a.setB(c), in my opinion it's better to be explicit about what's going on to avoid problems down the line.
Blocks are just anonymous functions with closures, so ruby and python are equals? But python doesn't have proper first class anonymous functions with closures. It only has a half-assed crippled version that is supposedly being removed in python 3. So clearly python is missing functionality that languages like ruby and pike have.
The problem sound rather like "linking an incompatible library version" than header problems occuring through use of the C++ preprocessor.
.h file by defines in other .h files." was a typo.
Java can have the same problem since it links in EVERYTHING at runtime. Put an outdated class in the classpath before or instead of the correct class and you've got a problem.
I don't think any other language handles the situation any better.
The only way to "fix" this is by doing some sort of version-number (timestamp?) checks, the mechanics of which aren't dependant on a specific language or it's features.
I still don't see how this problem is caused by the C++ preprocessor though, perhaps an example would help?
p.s. I hope "And I hope you can change the "effect" of an
Slashdot social media options: AIM, ICQ, Yahoo, Jabber and Mobile Text. Why no MySpace?
for (vector > p = v.begin(); p!=v.end(); ++p) cout >::iterator p = v.begin(); p!=v.end(); ++p) cout *p endl; Hot damn, somebody get me a cookie, I found a mistake in Bjarne Stroustrup's code!
<xml><I><am><so><damn>Web 2.0</damn></so></am></I></xml>
They don't have writers the caliber of Guy Steele or Kent Pitman, so it'll still read like gargling razor blades
Their legacy syntax straightjacket will insure the code stays verbose and hard to read. Compare:
struct ltXMLCh {
bool operator() (const XMLCh* s1, const XMLCh* s2) const
{
return XMLString::compareString(s1, s2) 0;
};
};
with
#'string<
or (comparing apples to apples):
(lambda (s1 s2) (declare (string s1 s2)) (string< s1 s2))
To a Lisp hacker, XML is S-expressions in drag.
No one has used C++ for any major operating system,
t ml
Windows XP, NT, 9x. See: http://public.research.att.com/~bs/applications.h
and no one has used C++ for any hardcore military project.
I'd beg to differ.
-everphilski-
>(eval (read))
(format t "~a" "You really should learn LISP.")
You really should learn LISP.
NIL
>
Not to add a pointless "me too", but I would also agree with this. I'd just like to add that this massive time for dealing with types does make C++ very unwieldy for quick prototypes if you just want to test an idea. To that end, I find the common approach of prototyping or doing quick utilities in python, and re-doing mission-critical stuff in C++ to be a great compromise.
Can you imagine what a C++ lambda construct would have to look like?
(lambda (x y) (- y x))
would turn into a mess like:
int lambda(int x, int y) { return y - x; }
And that's a trivial one...
To a Lisp hacker, XML is S-expressions in drag.
I also end up looking silly by placing paragraph break HTML on other sites I post. Everyone around Slashdot (just like -- name favorite feature -- C/C++) programmers gets in the habit of using proper paragraph breaks, but it is entertaining to watch a noob make a long post, or perhaps an old timer who has passed some brain gas, make a honkin run-on post.
I guess Slashdot could fix this and accept whitespace as a paragraph break, but I guess that would violate some deep principle. But I am not blaming Slashdot -- it is deep in the software developer culture to accept things the way they are and then holler at the newcomers about their mistakes brought on by the fractured syntax. How do you think the C syntax has become so viral?
it would do assembler, C, C++, and higher than C++ level
IMHO those four languages are better unified - that gives the programmer the most control.
Have you heard of the D language? It's not C or C++ precisely but is pretty close, has provision for using C APIs, has assembly, more function/object features and is easier to make more reliable code - see features kept and features dropped from C++:
D Programming overview
"With C++ I can write one piece of code that can process pixels with 8 or 16 bit integer channels or 16 or 32 bit floating point channels. Fanboys of Objective C and Java are obviously not writing image processing software."
s . Could have found a lot more stuff, but can't be bothered just to provide even more proof of the fact that you are talking utter crap.
And C++ fanbois are prone to assume silly things about other languages from what somebody they agree with says about them. As an example of this, the fact that Java has templates seems to have escaped you.
As to image processing:
Objective C: http://en.wikibooks.org/wiki/OsiriX_Specification
Java: lots of examples here, as Sun's JAI (Advanced Imaging API) is specifically designed for image processing. Google is your friend.
People are also doing image processing in Python because it is used by lots of scientists, and image processing is something they do. And of course good old venerable C, which completely lacks all the "++" bits which you seem to think are necessary for writing any type of software.
"Without such important features as operator overloading, constructors, stack-based objects, and references, I really can't take Objective C seriously."
And these are necessary to write software because... Oh, that's right, you need a Turing complete language to write any conceivable piece of software, and what's that? A language can be Turing-complete without having any of these? What strange heresy is this?
"I can't imagine it being used for much mission critical software, that's for sure."
It seems you are incapable of imagining lots of things that exist, but that's your problem. For example, one thing that has escaped your imagination is the fact that C++ is far from being the language du jour for writing mission-critical software: the bulk of what can truly be classified as mission critical (i.e. extremely high reliability stuff where lives are at stake such as medical embedded systems, aerospace, real-time operating system kernels, etc,) are written in C or Ada, usually with a liberal sprinkling of assembler. How can this be when these languages lack all of those amazing features that you insist are necessary for them to be taken seriously? Is it possible that they are missing critical pieces of functionality that can only be implemented by using references to pass parameters? Maybe you should tell them!
I'm not going to change your sheets again, Mr. Hastings.
Get off your soapbox. Some of us like languages that actually have syntaxes and can really do low-level work.
It is very likely that the sugary-syntax language you use is glued to the standard C library to meaningfully interact with your system, assuming you are using a *nix system. I cannot vouch for what goes on behind a Windoze machine. You must be a Python programmer. That is ok. It is a lot better than being a VB programmer. But Python has nearly reached the precipice to oblivion that Perl reached a few years back. It is out of vogue. Go back to the classics. Try guile! You can link C libraries in the same way. I do admit I am hoping for a renaissance for the Lisp languages in 2006. As for the elegant and necessary Lisp parentheses, just use Emacs show-paren-mode and you will never be bothered by matching ')', '}' or anything else.
an ill wind that blows no good
XML causes global warming.
#define foreach(x,it) for(typeof((x).begin()) it = (x).begin();it!=(x).end();++it)
This can be done because typeof is implemented in the GNU C++ extensions, but not in standard C++. Why not begin with a handy feature such as this?
Here's the two features I want:
unsigned, signed, signed, etc. The built in types should have size specifiers and all use the same names. The whole thing about incompatible long size is confusing and unnecessary. This also lends itself to hardware programming better. You could have an unsigned (i.e., seven bit number) handled by the compiler just fine by building in checks on the eighth bit of a byte instead of relying on the carry flag. It would be a wee bit slower, but still useful.
The second feature is some fixed data types. fixed would have sixteen bits for the whole number portion and sixteen bits for the decimal portion. unfixed would be an unsigned version of the same thing. Why do we need this? So that I can have a freakin cross-platform video and image library. libjpeg runs faster on my local box than on the $13k SGI box in the lab. Why? A nice fellow wrote the thing in fixed point MMX assembly and the Itanium chips don't have 32bit MMX support so it kicks back to the floating point overload of the DCT function. Shifting would also work directly on these fixed point numbers. I'm also a fan of making it so that shifting a floating point number inc/decs the exponent.
Who are the idiots you work with for whom this is a real issue? Or is it just you? I just don't see this "carnival of confusion" in the professional programming world that uses C++.
XML causes global warming.
Indeed: even C code that compiles under C++ can have a subtly different meaning that can bite hard in the form of intermittent bugs that can be extremely difficult to trace. IMO this is actually worse than languages like Java and C#, which are C-like but don't pretend that they are either supersets or "enhanced subsets" of C. It is also the reason why most C programmers use a C compiler rather than a C++ compiler, and also why most commercial C++ setups ship with a C compiler that gets automatically invoked on modules with a ".c" extension.
NB: Objective-C is a true C superset in that it will compile standard C programs just as a C compiler without the "Objective" bits would.
I'm not going to change your sheets again, Mr. Hastings.
BTW, when you say "fancy allowing standard operators to be overloaded" I think you mean "overrided". C has overloaded operators (+ is defined for int, char, short, long, float, double, etc). overriding lets you tell the compiler how to do addition for your custom bigint library, or whatever. You can misuse operator overriding, or you can misuse macros, each are there for a purpose, and each get misused by bad programmers.
No, the GP ws perfectly correct - it's called "operator overloading" (see the title of the chapter on operator overloading in Stroustrup's The C++ Programming Language). Amusingly, it just so happens that the word "overload" and its derivatives are themselves overloaded; in C++, overloading refers both to operator overloading and to function overloading, which refers to creating multiple functions with the same name that are distinguished by their parameters (which is what you were thinking of when you made the comment about the + operator, though + really is an operator, not a C++ function).
-insert a witty something-
Nothing on the scope that C++ is talking. The inline functions is syntactic sugar, we already had macros. Nice syntactic sugar, but still sugar. Complex numbers already existed, there were dozens of libraries that did them and did them well. Read the list of changes for C++, its a major turn in the language.
I still have more fans than freaks. WTF is wrong with you people?
Well, I wouldn't go so far as saying that C# or Java is more "modern" than C++ (Which is kinda stupid...); but to say that C++ is "well engineered"...
C++ is well engineered in the same sense of PL/I was well engineered- and it's becoming as complex and convoluted.
"Over engineered" would be a better description- and I'm a proponent of the language.
I am not merely a "consumer" or a "taxpayer". I am a Citizen of the State of Texas
how about being able to read in a string and use that as a variable name?
How about we sacrifice some virgins while we're at it as well? The word evil doesn't even begin to describe this practice, no matter the programming language. Could you give an example of where this might actually be useful?
People replying to my sig annoy me. That's why I change it all the time.
But I see that you *really* meant *pass* by reference, if you want to ensure that the function can have no side effects, cast the parameter to const. Otherwise, if you expect to write software without knowing what the functions do, you should not be writing software.
That's fine and dandy, but the fact remains that pass by reference makes it more difficult to understand code. There is no syntax at the place the function is called that indicates that it is pass by pointer (which is what pass by reference really is in C++) instead of by value, and this is by no means an insignificant difference. Thus you either have to check the prototypes or possibly miss an important distinction (and have it bite you in the ass later), when using pointer syntax would have made things clear from the get-go.
Bjarne put references into C++ in order to support overloaded operators for complex objects that use the same syntax as operators for basic types. This is pretty much the only reason you should use it (ask Bjarne). In almost every other situation, pointers are equally useful and more clear to someone reading your code and thus preferrable.
Passing references to functions is one of those things that comes from people gleefully trying to use every new feature, like making every member function of a class virtual even though it isn't needed. Thankfully it doesn't tank performance like using virtual everywhere.
P.S. Making a version of an operator/function that works with your object type is called 'overloading'. Making a new version of an operator/function with the same types as an existing one is called 'overriding'. But that's just me being pedantic.
The enemies of Democracy are
"Your DLL problems are a problem of Windows, not of C++"
To be fair, it can also occur on UNIX (a catch-all category which should be read as including Linux) with shared objects. But you are right in saying that this is not a C++ problem as such: shared libraries / DLLs are features of particular OS families that should not be specifically supported by a general-purpose programming language like C++.
NB: I share the general consensus that C++' handling of modularity leaves a lot to be desired. In particular, the loose coupling between headers and source modules together with the ability of any header to redefine the values of constants etc. imported from prior headers is both a potential and actual source of problems. I can understand C++ _supporting this_ for compatibility with C, but Bjarn should IMO have added another better system for use with new C++ code. If something like this had been done properly from the beginning, then they wouldn't have had to retro-fit name-spaces at a later date, because the module name could have also served as a name-space identifier, as was the case with Pascal and Modula-2, later borrowed by more modern languages such as Python and Java.
I'm not going to change your sheets again, Mr. Hastings.
Instead of tacking more features like threads onto an already bloated language, how about making some options that would make C++ codes more debuggable. I would love to have a compiler option that forces strong typing ala Ada in my codes. No automatic type conversions. No default constructors or operators to my classes being built. I would also love a sane I/O syntax. And while you are at it, please simplify the STL API. I know I am just being cranky but I would be surprised if there are a dozen people on the planet that understand the complete C++ standard as it is.
The truth is an offense, but not a sin.------R. N. Marley
I just read through the article and I must say that I am excited. The changes that they are proposing are so awesome. Each one is something that has frustrated me that C++ does not already do. Must of the past changes of C++ have made it much more complicated. They were good changes, but they did make the language more complicated. Apart from concepts, these proposed changes seem to make things simpler. I especially like the "auto" type. What a brilliantly wonderful idea. This is something that I have longed for. I love it.
Parent is correct, D is quickly becoming a very robust programming language specification. It still has some rough edges though. Even if the bugs and missing features preclude you from using it right now, at least read the specification thoroughly. You'll be pleasantly surprised, and want to check up on it on a regular basis.
Using the assignment library this is easy.
// for 'operator+=()' // bring 'operator+=()' into scope
// insert values at the end of the container
Here's an example from :
http://boost.org/libs/assign/doc/#operator+=
#include
using namespace std;
using namespace boost::assign;
{
vector values;
values += 1,2,3,4,5,6,7,8,9;
}
This, it seems, is not the way it will be implemented in the new C++. But lots of other stuff mentioned is already in boost (smart pointers, threads).
That said, if you're using gcc and GNU make, you may prefer the following:
/usr/local/strange_module-2.3.7
PREFIX =
CPPFLAGS += -I$(PREFIX)/include
LDFLAGS += -L$(PREFIX)/lib -R$(PREFIX)/lib
Most people forget the -R and assume that ${LD_LIBRARY_PATH} will be set appropriately by the users. IMHO, that's just dumb.
Of course, the example above is not very good if you're also building the strange module's library at the same time as the executable. But I'll leave *that* solution as an EFTS.
Do daemons dream of electric sleep()?
Bjarne put references into C++ in order to support overloaded operators for complex objects that use the same syntax as operators for basic types. This is pretty much the only reason you should use it (ask Bjarne). In almost every other situation, pointers are equally useful and more clear to someone reading your code and thus preferrable.
Well, I'm not beholden to Bjarne to be the final answer. Just because he designed the language, doesn't mean he understands everything about it. Like any feature in C++, when improperly used, it produces poor code. I really don't care if the parameter passing mechanism is known at the call point. If I know what the function does (which is the first thing you *should* know), then I automatically understand how things are passed around. When using pointers, the NULL issue is rarely brought up because it's hard to deal with. With references, you don't have this problem (ignoring NULL references since they're hard to obtain in the first place).
Mad Software: Rantings on Developing So
How much is "much"? C doesn't have all of those important features, yet it is the backbone of much mission critical software. Maybe by "take seriously" you meant "consider optimal" and by "used" you meant "preferred"?
> Could you give an example of where this might actually be useful?
I use it in both shell and javascript (njs interpreter) to save and restore state. State is stored in a text file, which, when executed by the running program, magically brings back the variables.
Of course, this is patently evil, and would never see the light of day in production code.
In a similarly evil vein, I have been known to grab a CGI query string in shell, split it across the ampersands, and eval the resulting data as code. This causes the CGI form variables to become shell variables, and your shell-script CGI can then merrily truck along and use them as it sees fit.
I'm not sure which is more evil. They are both useful tricks for writing VERY quick and VERY dirty code, but making them robust enough to expose to users would completely negate any benefits they had. If it was even possible.
Do daemons dream of electric sleep()?
ye gods. I'll actually admit to having done so in mIRC, which is already plenty evil all by itself, both as a program and in its scripting abilities, but what you're describing is of such an evil nature that it would require at least 4 superheroes to squash it. Bring on the Fantastic 4mat!
People replying to my sig annoy me. That's why I change it all the time.
...C++ is doing it via first evolving into Java 1.0.
So slowly C++ will become Ada? Are there really any substanive differences in Ada and C++0X other then using "{ }" vs. using "begin end" and simalar trivia? Ada, BTW is still very much in use but that use is restrited to a small range of applications. mostly to applications where people will die if there is a software bug like airplane flight control, guidance systems for cruise missles, nuclear power plants and so on. Not many web browsers are written in Ada. I think what kiled Ada for general use is a lack of a huge set of _standard_ libraries. C, C++ and Java and the other hand are populare because of thier libraries
Suppose I see this call in C:
The standard way to pass a large structure in C is by its address, rather than copying the whole thing, whether or not the structure is going to be modified inside the routine. So here I know that a, b, and c might be modified, but then again, they might not. How is this any better than C++? After all, every reference argument in C++ code becomes a pointer argument in the equivalent C code. At least with C++ I have the option of making a reference "const".Overloading operators allows for useful syntactic sugar -- that's why the C++ Complex class is so much more pleasant to use than the Java Complex class. It can of course be abused. So what? Any language feature can be abused.
As for gargage collection, 95% of the time is isn't needed -- the simple paradigm of allocating storage in constructors and deallocating in destructors does what you need. But for the other 5%, when you have no way to know when the lifetime of an object is over, there's just no good substitute for a garbage collection system. I don't know what the C++ garbage collector will look like, but if it allows some things to be garbage collected and others not it will be a very useful addition to the language while not forcing every damn object to be garbage collected the way Java does.
If you're interested in reading about possible future extensions to C++, check out the official home of the C++ Standards Committee. The papers page links to all the "mailings" containing every paper submitted to the committee, as well as draft standards and such. There's a lot of interesting ideas floating around: true "metacode" macros (like Lisp), flexible initialization (so that the {...} initializer could be "overloaded" on your own classes), automatic type deduction, etc.
I agree.
Bjarne Stroustrup seems to be the only person who has the mental capacity to guide the development of C++. However, he is taking a very leisurely view of improving the language, in my opinion. We need those improvements 8 years ago.
Java is attractive, but writing in it means getting involved with Sun's mismanagement, which is so bad it may eventually kill the language.
C# is attractive, but using it means being under the influence of Microsoft, a company which is often adversarial toward its customers.
As in other fields, we suffer greatly because of the poor quality of our leadership.
There is no syntax at the place the function is called that indicates that it is pass by pointer
// a few dozen lines of code here... // so, is this pass by value or by pointer?
Not necessarily the case with explicit pass-by-pointer either. e.g.
int foo = 1;
int* bar =
do_something(foo);
Bjarne put references into C++ in order to support overloaded operators for complex objects that use the same syntax as operators for basic types. This is pretty much the only reason you should use it
I strenuously disagree! Passing a parm by reference, rather than pointer, makes it well-nigh impossible for the parm to be null. (If you play truly evil casting games you can manage to make it happen, but it really requires a deliberate attempt.) Our coding guidelines specify that any parms that can't legally be null should be passed by ref (or const-ref, if possible). No more sanity-checking-for-null at the entry to the routine...
In point of fact, I find this the single best use of references -- since I consider operator overloading something to be avoided in most cases. (Overloading operator* to do matrix multiplication -- sure, fine. Overloading the left-shift operator to do stream I/O.... wtf?)
What are you smoking?
Objective-C has its pros and cons (which I don't want to get into here), but advanced template support is NOT among them.
Assuming of course that I want to put a lot of complex data into my code rather than load it from XML or a database, I would seriously consider creating the XML files anyway. That would make switching to loading XML at runtime later a bit easier if I had a change of heart. Then I'd write some XLST to generate the C++ initialization from the XML source. Not that I expect any of this to change anyone's opinion on whether this is a shortcoming of C++ or whether it should be considered as a possible new feature.
Someone else asked why you would want to hard-code complex data. I can think of a couple of reasons. Sometimes your data is essentially static, but isn't composed completely of built-in types. State tables are a rich source of examples. In an embedded system, you may be hard-coding all sorts of things that could be expressed in a database or XML, but you can't afford the storage for the libraries and the database. Finally, if you need to write a small program that loads fast to do a quick job, you don't want the program to load and then have it read it's configuration from somewhere if that configuration is static.
The net will not be what we demand, but what we make it. Build it well.
Yes because the thing that C++ really lacks is features bloat.
Bad analogies are like waxing a monkey with a rainbow.
I got tired of complaining about C++, and decided to do something about it. The result is the D programming language.
*drooling* awwwwww, hookay!
int foo = 1; // a few dozen lines of code here... // so, is this pass by value or by pointer?
//...
:)
int* bar =
do_something(foo);
This case is perfectly clear: foo is passed by value. If we can assume do_something(foo) takes an int instead of an int&. I'd have to know that to say for sure, which is exactly the problem with references.
I'm not sure that example worked as you wanted. Did you mean to pass bar or something (in which case it would still be clear, bar is passed by value, what bar is pointing to is passed by pointer)?
I strenuously disagree! Passing a parm by reference, rather than pointer, makes it well-nigh impossible for the parm to be null. <snip> No more sanity-checking-for-null at the entry to the routine...
But it doesn't make it nigh impossible for the object to be invalid. Checking for input validity is not something you can skip no matter your passing method. And checking for non null is simple:
void pointerPassing(int* foo) {
assert(foo);
In point of fact, I find this the single best use of references
If the best use for references is to avoid a one line check at the expense of making the calling code more difficult to understand, then I'd say there's no use for references at all.
since I consider operator overloading something to be avoided in most cases. (Overloading operator* to do matrix multiplication -- sure, fine. Overloading the left-shift operator to do stream I/O.... wtf?)
The rule I use, which I've heard Bjarne himself utter while simultaneously destroying with the stream operators, is that the operator should have an obvious meaning analagous to the built-in operator. E.g. adding strings and complex numbers both have obvious expected meanings. Writing to a stream is nothing like shifting, so yeah. That's why I still use printf().
But sometimes operators do make sense (e.g. a 'uint128_t' class that is supposed to provide the same functionality as the uint64_t type) and for that you need references.
The enemies of Democracy are
preprocessor metaprogramming. It's a very powerful tool
"powerful" in the sense of "as powerful as a Turing machine", I suppose.
Template/preprocessor metaprogramming is a horrendous hack. It basically happened by accident because the addition of templates "upgraded" the compiler to have a Turing-complete language embedded within it. Not that anyone realized this while they were actually *designing* templates.
Well-designed "metaprogramming" would use, get this, a programming language, with sane syntax, not the mess that template syntax is; C++ was already so crowded with line-noise operators, they had to separate less-than signs with spaces. It would also have real programming semantics, instead of hijacking the type system to provide flow-control.
Lisp basically got this right, by allowing meta-programming to use the same language and operators that the underlying language has.
The problem is that you are forced to use textual inclusion to build pretty much any project bigger than a single source file. There isn't a real module system as in many more 'academic' languages like Modula-2. What I mean is: suppose you would like to use libpng in your program. So you #include the libpng headers. Purely as an internal implementation detail, libpng happens to use zlib. Its header files #include some of the zlib things, which means that zlib is now dragged in at the top level even though you did not ask for it. Ideally, the zlib functions should be available only in the libpng source files that asked for them, and if you separately wanted to use zlib (perhaps a different version) in the main project you should be able to do so without needing to know or care about whether libpng also uses it.
Also as the UNIX-HATERS Handbook notes:
In other words it is very hard to write automated code browsing tools or refactoring tools for C and C++ because you can't parse a given source file without textually expanding it (and thus dragging in megabytes of headers). Things like etags are only approximations. I guess I'm contradicting what I said earlier: the mere existence of the preprocessor is bad, because it makes life difficult for IDEs and code browser tools. There are some good points to the preprocessor, but in this day and age when any compiler can do inlining, not many.
-- Ed Avis ed@membled.com
You cant find the discpline to write simple code within?
You must have it imposed from without?
Perhaps it is not the tools that need changing.
emt 377 emt 4
I really don't care if the parameter passing mechanism is known at the call point.
// How is this difficult? This argument is a non-starter.
Then you don't care about writing maintainable code. That's fine, but having had to frequently maintain and modify code written by others I do care.
If I know what the function does (which is the first thing you *should* know), then I automatically understand how things are passed around.
Do you use expressive variable and function names? Or is your code riddled with X(a) + Y(b) When using pointers, the NULL issue is rarely brought up because it's hard to deal with. With references, you don't have this problem (ignoring NULL references since they're hard to obtain in the first place).
void someFunc(int* foo) {
assert(foo);
The enemies of Democracy are
Did you mean to pass bar or something (in which case it would still be clear, bar is passed by value, what bar is pointing to is passed by pointer)?
:-(
Yes, I mistyped
And yes, it is clear that bar is passed by value, but the fact that your local value can be modified is not clear.
But it doesn't make it nigh impossible for the object to be invalid
No, but is a particularly common (and fatal!) case that can be eliminated at compile-time rather than caught at runtime (hopefully in testing, rather than by the customer...)
The Borland of today seems better than the Borland of before, but I got scared by Borland's previous bad management.
Geeze, I need to rember to use preview. /smacks self with the clue stick.
// How is this difficult? This argument is a non-starter.
Well, I'm not beholden to Bjarne to be the final answer.
Of course you're not, but he does have a good grasp on the language. And he certainly knows why he put something into the language.
I really don't care if the parameter passing mechanism is known at the call point.
Then you don't care about writing maintainable code. That's fine, but having had to frequently maintain and modify code written by others I do care.
If I know what the function does (which is the first thing you *should* know), then I automatically understand how things are passed around.
Do you use expressive variable and function names? Or is your code riddled with X(a) + Y(b) < zz ? After all, the first thing someone should do is look up what X, Y, a, b, and zz are, and then everything will be clear from then on! Or do you helpfully clue people in to what all these things are and what they are for by giving them descriptive names?
You have to look at this from the perspective of someone other than you, the original author of the code. They might be your successor after you leave for greener pastures, or just someone who needs to modify the code without your personal guidance. They probably aren't starting by scrutinizing every function prototype, they're probably trying to understand a particular block of code they care about which calls this function. Yes, they can and should understand what the function does but having the usage of the function implied by it's name, it's parameters, and the way those parameters are used at the calling place makes the code easier to understand, both at initial bring up and when coming back to it in the future.
Pass by pointer makes for easier to understand code and if you care about that is preferrable. If optimizing ease of understanding isn't your goal, that's fine. Not everyone needs to care about that.
When using pointers, the NULL issue is rarely brought up because it's hard to deal with. With references, you don't have this problem (ignoring NULL references since they're hard to obtain in the first place).
void someFunc(int* foo) {
assert(foo);
The enemies of Democracy are
KDE is open source. All KDE libraries are either LGPL or BSD. The Free edition of Qt is GPL/QPL. All of those previously-mentioned licenses are OSI-approved.
Please keep your stupid anti-KDE FUD elsewhere.
Not a joke, a research project. Thus, Stroustrup's willingness to include any "feature" that someone suggests: "Oh sure, we'll put that in and see how it works out."
Neither of these statements is true. He was at Bell Labs, but in no ways did he intend C++ to be a research project. He wrote it to solve real-world programming problems, to make real-world programming easier. How much he succeeded you can argue, but he did intend for it to become as widly used as it is.
As to your second point, follow the other fellow's advice and read D&E sometime.
I can't believe they're putting still more lipstick on this pig.
What you have just described is Apple's Frameworks This might work on other systems with gcc aswell. Since I got my first iBook and learned about frameworks, I've pondered, why the heck doesn't any of the linux distributions use them.
That's fine and dandy, but the fact remains that pass by reference makes it more difficult to understand code. There is no syntax at the place the function is called that indicates that it is pass by pointer (which is what pass by reference really is in C++) instead of by value, and this is by no means an insignificant difference.
I'll agree to some extent, but I have two things that I feel need to be added:
1. Pass by reference doesn't make it difficult to understand code, the lack of syntax at the call site does. For instance, C# allows reference parameters, but you need to specify that at the call site too.
2. C's style of things hardly makes things any better. If I have a function foo(some struct* x), why am I passing x by pointer? Is it just to save time and duplicating x on the stack, or is it because foo is actually going to change it? You can't tell that from looking at the call site either, even if C had const or in the extensions where it does. My experience is that most of the time most objects are passed by reference or pointer. That means that loss of readability from reference parameters in C++ really only show up when you're dealing with primitive types.
And he certainly knows why he put something into the language.
// How is this difficult? This argument is a non-starter.
Again, I don't care why he put it in the language. I care about how it can be best used in reality. I don't think that current use of templates was envisioned when it was designed, but it seemed like a good idea, so it was added. Your original statement used Bjarne's approval as proof of correctness. That's the false logic that I disagree with. Sure, he has a lot of good ideas. That doesn't mean he's right, not even close.
Pass by pointer makes for easier to understand code
Your entire argument logically follows from this statement. However, I don't agree with this statement, so I don't agree with the rest of your argument.
I don't think it makes for easier to understand code. The presence of pass-by-reference should be obvious from the name of the function, not the requirement to pass a pointer.
Do you use expressive variable and function names? Or is your code riddled with X(a) + Y(b) zz ? After all, the first thing someone should do is look up what X, Y, a, b, and zz are, and then everything will be clear from then on! Or do you helpfully clue people in to what all these things are and what they are for by giving them descriptive names?
Don't be ridiculous. Of course I use descriptive variable names. That's why I don't need to use pointers to pass-by-reference. Because my function names are good. And no, I don't expect my maintainers to understand every last function before they read my code. But I do expect them to go look at the header if they want any more than a basic understanding of what the function does. I don't include comments in my function names, I put them in the header, where they belong.
Yes, they can and should understand what the function does but having the usage of the function implied by it's name, it's parameters, and the way those parameters are used at the calling place makes the code easier to understand, both at initial bring up and when coming back to it in the future.
Ok, so your logic is that the more information is included at the call point, the better. Ok, then why don't we include all kinds of other information there too. How about including a cast to the true parameter type so that I know the true type of each of the parameters? How about adding a little comment for each parameter that gives the name of the parameter local to the function? Or any number of things that might help our plucky maintainer? Because it's all in the header file.
void someFunc(int* foo) {
assert(foo);
Because if I use pass by reference, I don't need to do it at all. I don't need to even worry about the assert firing in all those rare cases I didn't think about, or know about.
Mad Software: Rantings on Developing So
I've heard Bjarne himself utter
This is religion, not logic.
Mad Software: Rantings on Developing So
There is Lisp, and there are lower-level languages used for systems programming. That and maybe something for games, multimedia and other performance-critical apps.
C's style of things hardly makes things any better. If I have a function foo(some struct* x), why am I passing x by pointer? Is it just to save time and duplicating x on the stack, or is it because foo is actually going to change it? You can't tell that from looking at the call site either, even if C had const or in the extensions where it does. My experience is that most of the time most objects are passed by reference or pointer. That means that loss of readability from reference parameters in C++ really only show up when you're dealing with primitive types.
Not only that, but I just thought of something else:
If you don't have const in C, the situation is actually better with C++, references, and const, because the almost universal idiom is to pass by const reference to save space. If you see a reference parameter that isn't const, it's at least somewhat safe to assume it will be changed. (The other main possibility is that people were lazy with classes and didn't make them const correct, forcing them to use non constants.) You can tell if a parameter is const by the function signature. Not as good as the call site, but still better than in C where you can only tell from the method implementation (or documentation) that a parameter isn't changed.
The goal of C++0x is not to add a bunch of new features to the language.
Two of the driving goals of the committee are to prefer library extension
to language extension and to focus on simplifying current features.
Remeber that the standard library specification is a major part of
the standard. And standard library extensions are very different than
language extensions.
The actual "new features" that the Bjarne was discussing focus on
simplifying and streamlining current features and syntax. For example,
while template typedefs and auto iterator types are language
extensions their goal is to simplify a current language feature: templates.
The possible exception to this is the addition of "concepts". However,
information about the design of "concepts" is so sparse in that article
that it is difficult to form an opinion.
Jake
Spoken (Natural) languages are extremely complex and extremely useful. Programming languages can profitably be just as complex if they were good enough to last for as many decades as we use natural languages! If you're going to learn a new language every 5 years it constrains how complex that language can be. If you're going to use it for 50 years it's a different story. C++ isn't good enough to use for enough years to be worth the complexity.
Nevertheless, the choice of programming languages should not determine whether the app is garbage-collected or not. Although that will greatly impact libraries.
C++ is a research language that should be replaced by something that is not afraid to be incompatible with it. Java and "D" are nice tries but tie garbage collection to the language. C# is disappointing considering the size of the organization behind it. And is also tied to GC.
Software systems often contain components that need to be coded close to the machine to obtain maximum performance or flexibility or power. At least the OS. Those same software systems always contains portions of glue and convenience code that does not need to be coded close to the machine and should be coded at as high a level as possible. The challenge to language designers is to create a programming system that spans as great a height as possible without forcing the coder to migrate to different syntaxes and toolsets. C++ and OO are an attempt but don't really make it.
I18N == Intergalacticization
// 6 lines in Java, not sure if the code does exactly the same
import javax.swing.*;
public class F
{
public static void main (String[] _args)
{
JDialog form = new JDialog ();
form.add (new JButton ("Hello, World!"));
form.show();
}
}
Million Dollar Screenshot
Or is it you? Show me a piece of code that runs faster with a C compiler than the same piece of code with a C++ compiler from the same manufacture. Maybe you don't understand that if you write code that doesn't use the "slow" features of C++ its the same speed as C. Even then when you use virtual methods, compare them to the performace you get with structures of function pointers in C. Then there are things that acually make C++ faster than C, like for example templates and exceptions. Look up template meta programming on google if you don't believe me. I know of at least 1 compiler that accually generates faster code for the C++ virtual methods can get generated by the C function pointers. I think at this point most of the C compilers out there are acually just C++ compilers with a slightly diffrent parser running on the frontend.
I don't think C++ is now, or ever was (or with the way these "extensions" keep showing up) - or ever will be suitable for Systems Programming.
This is complete and utter BS, I have written a number of drivers using C++ in enviroments that didn't officially support C++. I have also written a microkernel that runs on a number of embedded ARMs in C++. C++ is a wonderful systems programming language, I no longer have to manage function tables, deal with a lot of error handing etc. System calls are a natural place to create a "transaction" that can be aborted by an exception, as are SLIH's the list goes on. I'm not the only one, a number of other people have C++ based kernels and drivers. Writting an OO kernel also encourages you to have interfaces between the diffrent subsystems, this is something linux strongly needs and doesn't have.
cout
cout is in my opinion stupid, and I don't use it, so I don't care if its slow (plus its not internationalized, and hard to convert, unlike the printf family). Plus most people don't understand that it tends to creates temp objects all over the place, and that is what is slow not cout.(this reminds me of Java, which isn't always slow, but it encourages practices that are)
Because the C++ programmer infrequently can understand what his runtime is doing- and is not encouraged to know the interface by which C++ does it's magic (because nobody knows- they're still trying to figure out how to make some C++ magic work in a way that isn't slow)- a C++ systems programmer needs a C++ runtime. Nobody has one in systems-space, so the C++ programmer (which isn't a programmer of C++) needs to write it.
This is utter BS too, it isn't any harder than C, in fact its almost the same as C except for virtual methods, RTTI, and exceptions. The rest is basically all compile time. RTTI is off by default on most compilers because it can slow things down, exceptions and virtual methods usually only take a little while to understand how they work with a given compiler. If its not documented then a few minuits in the RTI and stepping through the call or excption with an assembly debugger should make it perfectly clear. In fact as part of using C++ in a kernel mode enviroment I have implemented a number of C++ startup and basic support libraries, the biggest one was probably 200 lines of code (because you can't include the full C++ or for that matter C runtime for usermode, with C that code is usually already in the kernel so you don't need to generate it again). Mostly it was simply changes like overridding global new and making it call the kernel allocator, setting up the module/driver/kernel load routine to call the constructors/destructors for global objects, and other really simple things like that.
All things being equal, if you can write C and just use a few of the features of C++, it will likely be worth it to your project.
All things are not equal of course, and the use of C++ tends to lead to unmanageable complexity, as soon as you get the first coder on the project who's enamored of such misfeatures as templates or operator overloading.
-jcr
The only title of honor that a tyrant can grant is "Enemy of the State."
I realise this is a joke, but don't you have to boot the kernel before you can even access the /dev file system?
Great. Just what we need. A language that looks like leet-speek for "cocks".
Moderator hint: a comment is neither "Flamebait" nor "Troll" if it is true.
Yes, "overriding" is only used when talking about polymorphic (virtual) functions in derived classes. The function in the derived class overrides the one in the base class.
in C++, overloading refers both to operator overloading and to function overloading, (which is what you were thinking of when you made the comment about the + operator, though + really is an operator, not a C++ function).
There is no semantic difference between a function and an operator that operates on at least one user-defined type. The "function" uses function-call syntax and the "operator" uses infix syntax.
If foo is a user-defined type, then (foo + bar) is entirely the same as operator+(foo, bar) . In fact you can even use the latter form if you want (although that kind of defeats the purpose of operator "overloading").
"Little does he know, but there is no 'I' in 'Idiot'!"
I've been programming C++ professionally for 10+ years now in a near-real time field. A few years ago I started using C# for offline things (e.g. tools), and most recently, a domain-specific language for large chunks of the runtime. Some of our team uses C++, some use the DSL. The C++ guys are orders of magnitudes slower to produce results. The primary problem is compile and link time. Getting thousands of C++ files to compile quickly is a fulltime job in itself, and requires thought from every programmer all the time not to #include absolutely everything. (Feel free to respond with "try this!", but I probably have). C#, Java and Python are near instantaneous, and do not require time twiddling includes or forward declarations. If the committee could organize compiler developers to progress C++ away from #include files and towards live code databases (or whatever is required) we will be much better served.
This sumarizes most of the problems I've seen in C++. Many people seem to be under the impression that because C++ is widely used, that it is a good language, or at least well adapted to the tasks it is used for. In reality, of the many many languages I've used, it is one of the most poorly put together and your writeup sumarizes why that is.
I'd like to add why I believe that C++ *is* so widely used.
1. easy access to C libraries. all the critical libraries are written in C, so there's no need to do language bindings (although wrapping some constructs in a class is still smart).
2. momentum. C++ seems/seemed like the natural next step to the many many C programmers out there. Businesses want to be able to hire from a large pool of talent. Also, C is pretty nice as far as portable assembly languages go, and so programmers who developed an afinity for C tend to assume that C++ will be just as nice to work with.
3. templates. templates are a really horribly implemented in C++, really just a glorified macro, but they are still extremely powerful and not long ago they were a feature that other mainstream languages lacked. Now virtually every language has a better implemented Generics. C#'s are pretty nice. See Ocaml or SML for a language with REALLY nice generics.
4. the belief that C++ is fast. As far as *compiled* languages go... not really. C++ may stack up well against Python and Java, but neither of these languages were designed to be compiled directly to machine code (although hacks do exist...). However, C is generally considered to be faster than C++, and Ocaml (a much higher level language which implements garbage collection) is about the same, maybe a little faster. One reason for this is that C++ tends to suffer from code bloat, which causes cache misses, which majorly slows down modern hardware. The code bloat happens because C++ tends to over-inline, any member functions in a header are automatically inlined, and because instatiations of templates are often duplicated.
One feature that would be nice to bring along from C++ to newer and better languages is easy bindings to C. If this happened, probably the largest real reason to use C++ would disappear. Here's how I'd do it if I were adding this feature to language X.
1. Define what primitive types in X are equivalent to what primitive types in C. Define a special syntax for accessing non-garbage collected C structures and pointers (similar to what C# does with com objects).
2. Make the compiler understand how to read function prototypes and type definitions out of C header files. Treat a C header file like a module in language X (assuming X is statically typed and has something like modules in C/Python/Sml/Ocaml or namespaces in C++/Java/C#). Now C functions can be called as naturally from language X as from C.
Ever work on a development team? You have to impose coding standards, especially with a rediculous language like C++, because not everyone will code to the same standards.
You're right though, if working as an individual, you should be able to write clean C++ using a subset of the complete language.
Jeremy
Diffr'nt strokes and all that; to me, the design of D is practically a bullet point list of ways to undo the things that Stroustrup and co. understood and got right but Java and friends got wrong. The design gives up most of the flexibility and power, in exchange for what? A garbage collector and, in Java's case, an extensive library (most of which isn't very good)?
If you want a higher-level language with a different balance of power vs. safety, there are many much better choices than things like D. On the other hand, if you want the power and you're smart enough to take advantage of the lower-level features in something like D, you're probably smart enough not to make rookie mistakes in C++ and to use the extra tools it offers effectively. I just don't see the target audience for the middle-ground languages. Java was born of hype, C# was born of exasperation with Java, and D was still-born, as you say yourself:
Well, if D is to become even a shadow of what C++ is already, it's pretty much going to have to overcome these fundamental drawbacks. It's tough; obviously a lot of hard work has gone into it. But as I said, I think it's a product with no market, trapped between the more powerful and much more established C++ on one side and the more flexible and productive "scripting" languges on the other, and squashed under theoretically sounder academic languages with better underlying programming models for good measure. You only have to look at the... not entirely representative... features checklist on the D language site to see where the design came from.
Perhaps there is a reason that, as the D site itself notes, most new languages appearing today are either from the academic community and showcasing more theoretically robust programming techniques, or from the business community and based on quick and effective development?
If you disagree, post your argument. (-1, Overrated) isn't your personal censorship tool for views you don't like.
My apologies, you're correct. I was under the impression that const within C was a compiler extension and not standard.
(The point of my original post though, that you still can't tell from the call site if an argument will be modified when passed by pointer, stands.)
Doesn't the language need LESS complexity? tone
tone
Your original statement used Bjarne's approval as proof of correctness. That's the false logic that I disagree with. Sure, he has a lot of good ideas. That doesn't mean he's right, not even close.
/. poster. It was not intended to be a logical proof, though I won't fault you for assuming it was. Of course he isn't always right. Except in this case he is right.
/*generateFaults*/, false /*write*/, true /*read*/, true/*code*/) is vastly more helpful. Python (and other languages) do this one better and don't require positional arguments, you can assign to the parameter name. E.g. optParser.add_option("--wiki", default=False, action="store_true", help="Generate Wiki-friendly table output with '|' between columns"). Nice, eh? In simple cases it isn't needed, in complex cases it keeps you from having to remember the order arguments are required to go in. This can make the code much simpler to read, and prevent you from having to constantly refer to docs/man pages/header files.
A lot of people would grant more weight to the opinion of Bjarne Stroustrup, inventor of the C++ language, over Chris Burke, random
Your entire argument logically follows from this statement. However, I don't agree with this statement, so I don't agree with the rest of your argument.
You're backwards. "Pass by pointer makes for easier to understand code" is my conclusion, not the axiom.
Don't be ridiculous. Of course I use descriptive variable names. That's why I don't need to use pointers to pass-by-reference. Because my function names are good.
Okay, maybe your function names are way better than mine, then. I'm trying to imagine how that would work for a non-trivial example. functionThatDoesFooWithParameterNPassedByReference () ? Hungarian notation? Help me out here.
Also, does this mean that you do see the value in making the pass by value/pointer distinction clear at the calling point instead of making them refer to the header file?
Ok, so your logic is that the more information is included at the call point, the better. Ok, then why don't we include all kinds of other information there too.
Yes, with the common sense caveat that there can be too much of a good thing. If it isn't an onerous burden on the author, and doesn't as a side effect make the code harder to read (e.g. including the entire function comment block before every call), then indeed why not? A single amphersand is hardly an onerous burden, and provides useful information.
How about including a cast to the true parameter type so that I know the true type of each of the parameters?
If the casts are non-trivial, then this would be good idea. The hidden costs of things like automatic casts creating temporary values are part of why C++ has a reputation for being slow. Making them explicit helps them be found and possibly optimized, eg by doing the cast outside of the loop when possible.
How about adding a little comment for each parameter that gives the name of the parameter local to the function?
This is a very good idea. Positional arguments can be confusing and difficult to remember, especially if you use constants. Something like translateAddress(linearAddress, true, false, true, true) can be maddening to read. Instead, something like translateAddress(linearAddress, true
Or any number of things that might help our plucky maintainer? Because it's all in the header file.
If it would be helpful and isn't an onerous burden. Making your maintainer refer to the header file unecessarily is a good way to get your name cursed by said maintainer. But I'm a little confused -- on the one hand, you say the maintainer should have to read the header file, but on the other you say that it should be clear that the parameter is passed by reference at the calling point. I'm getting mixed messages.
Beca
The enemies of Democracy are
But it doesn't make it nigh impossible for the object to be invalid. Checking for input validity is not something you can skip no matter your passing method.
;-)
If the input isn't valid, nothing you can legally do will find it.
And even so, it's one less thing that you have to test for.
And checking for non null is simple [then an assertation]
You just moved to runtime what the compiler could have enforced (as much as anything can be) for you at compile time.
If the best use for references is to avoid a one line check at the expense of making the calling code more difficult to understand, then I'd say there's no use for references at all.
It also symplifies syntax in the called function. There are other places where references are "necessary" though (for instance the return value of vector::operator[]), so they couldn't be removed from the language entirely even if you didn't allow them in argument lists.
(And I posted another comment about how I don't find even the readability argument in favor of passing by pointers unconvincing.)
The rule I use, which I've heard Bjarne himself utter while simultaneously destroying with the stream operators, is that the operator should have an obvious meaning analagous to the built-in operator. E.g. adding strings and complex numbers both have obvious expected meanings.
It's good rule, and one reason why I think that the proposed someVector += 5, 6; syntax is absolutely awful.
However, I think that an exception can be made for the shifting operators and input and output partly because of the very long history that they have, and partly because (to my knowledge) the shifting operators were pretty much invented for programming. +, *, etc. all have meanings we've seen since kindergarden or before; << doesn't. It makes sense, but then it also sort of makes sense for stream operations.
That's why I still use printf().
And lose flexability and enforced type safety?
(I know this is a war I can't win, but: I think that printf syntax often looks nicer, but it's harder to learn, a lot harder to understand if you don't know it, and isn't typesafe. You also have issues with how you output with classes because you can't make the printf formatting string accept new switches, and couldn't pass a non-POD type anyway. There was a language extension proposed to allow typesafe, variable length argument lists, which would have fixed some of those problems. I haven't heard anything about it for a long time though (I didn't necessarily RTFA now though), so I doubt it will come to fruition. That would have been nice though.)
No, it was clearly neither. If you read the whole sentence, you'd see it was instead irony.
/. post into a step in a formal proof. This is idiocy, not logic.
You're trying to convert every phrase and sub-phrase of a
The enemies of Democracy are
fonbio,
As you seem to have some experience with both, could you try to summarize the main differences between Scheme and Lisp?
Ah, here's another point that I didn't think of before:
You're all talking about how passing by pointers is good for readability because it enforces documentation at the call site that it can be modified.
Here's one way, related to the null pointer point (no pun intended), in which passing by pointer hurts the self documentation of the code. It's not uncommon to find functions that can accept a null pointer as an argument. A lot of unix calls in particular will both set a non-null pointer argument to and return a value. (I can't think of any off the top of my head, but if you want I'll find one.) Having a reference parameter documents from the syntax of the code (the strongest documentation you can have) that null values are prohibited; having a pointer does not.
In other words, the issue of the validity of a null value goes beyond just checking for improper parameter values.
I've seen advice that addresses this point, and recommends the use of reference parameters for situations in which null is invalid and pointers for when null is valid for this very reason. Sutter and Alexandrescu give this advice for when to pass by pointer and when to pass by reference:
What I find amazing about the group of C++ detractors as a whole is how rarely I comprehend the claims put forward about the vaguely defined desirable language ~C++.
r e+Java+isnt/2100-1012_3-5903187.html
5 0,39129961,00.htm
s plus&seqNum=200&rl=1
I think "you don't pay for what you don't use" is a fundamental design flaw of the language.
What is the precise claim here? That the entire language niche of pay-as-you-play languages should have remained empty? That C++ was the wrong language to occupy this niche? That there is a finite set of everyone-pays-all-the-time features that could have been added to C++ without compromising the language's scope or applicability? That any two people asked to write down such a list would produce a non-empty intersection?
Pay-as-you-play enables compositionality: the very idea that libraries like Boost can exist and be 90% as effective as if those same features had been designed into the language. It's the 10% that Boost doesn't achieve that gets folded back into the core language.
One guy was ranting that the true test of cohones is what the designer removes from the language, while another long post was devoted to a laundry list of "how could this language not have all these kitchen sinks so late in the day?" Which is it? You can't have minimalism in all places all of the time. Minimalism to the compiler vendor is a different beast than minimalism to the end user.
Ada had generics in 1983. Yada yada yada. What do you get when you start with a clean slate in 1995?
Does it thrill Marc Andreessen?
http://news.com.com/Andreessen+PHP+succeeding+whe
"Java is much more programmer-friendly than C or C++, or was for a few years there until they made just as complicated. It's become arguably even harder to learn than C++," Andreessen said. And the mantle of simplicity is being passed on: "PHP is such is an easier environment to develop in than Java."
Does it thrill Miguel de Icaza?
http://www.builderau.com.au/program/work/0,390246
The problem with J2EE really is that it became very, very academic and the complexity of all these perfectly designed systems in schools does not necessarily map when you have deadlines and all kinds of other things.
http://www.informit.com/guides/content.asp?g=cplu
When Java designers decided to disallow operator overloading, they cited C++ as an example of the inherent woes of this feature. As usual, they got it wrong, which is why operator overloading is slowly but surely creeping into Java just as generics recently did.
Does it thrill Sun insiders?
http://idevnews.com/CaseStudies.asp?ID=170
Peter Yared, former CTO for Sun J2EE app server unit says Java/J2EE may lose out to Open Source technologies in the future, as IT managers are architects get tired of the time and cost of building in Java.
The sad fact is that few of the C++ detractors out there could do any better than Java, and Java didn't hit its own sweet spot any better than C++ mapped to its own misbegotten design criteria.
In this respect I would like C++ be more like Java (or TurboPascal for the matter) where interface declarations and compiled code are unified
One thing that Java does well is put the interface to something in its compiled code. This also means that anyone can look into your interfaces from your compiled code. :)
In C, you could choose not to give someone your headersand they could never (easily) use your code, but the other code you distributed which needs it could still use it. Consider a third party library, for example. In my C/C++ days, I often wanted to use a library that another library I was using called into, but I couldn't do so because I didn't have the headers for it.
In Java you can achieve some of this with signed jars, and good use of public/private/protected/etc., but you simply can't give expose a public method in your JAR to one fellow and not to another.
Still, I manage to just fine without this :)
With the exception of ADA and maybe Modula-2, J2SE5 is one of the most type-safe languages I've used.
Java's "typecasting" is not like a C-cast, but rather like a full C++ dynamic_cast with RTTI enabled.
There is a big difference between type-safe runtimes and compile time type checking.
Where pretty much every language other than ADA falls down is their lack of numeric precision enforcement -- it's almost impossible to implement correct calculations in C/C++ without unwinding the statements so you can do correct result truncation after each operation involved. Languages which do such precision checking and enforcement don't suffer when automatic type conversions are performed, because you get told about the overflow/underflow issues.
Don't think for a minute that the C++ "void *" is anything like Java's "Object". The former is just an address/pointer, the latter carries type information.
I do not fail; I succeed at finding out what does not work.
If the input isn't valid, nothing you can legally do will find it.
In the sense that your reference/pointer might be referring to a deallocated (and possibly subsequently re-allocated) object, sure. That feeds into the issue that refrences are not a magical fix for memory management bugs, but that's a digression. I meant in the general sense that one must verify all inputs for logical validity. Indicies must be in the correct range, flags must have understood values, that kind of thing. Most substantial functions I write start with a block of assert() precondition and parameter checks, and checking for a null pointer is just one more. Granted, it is one more.
You just moved to runtime what the compiler could have enforced (as much as anything can be) for you at compile time.
I don't see how that is the case. Obviously there is a runtime check that didn't exist before, but in situations where one could actually get a null pointer I don't see how changing to references fixes it at compile time. I can only see it in the sense that you can't use new() to assign to a reference and then forget to check for null like you can with pointers, but that's just avoiding the functionality, not fixing the problem. I'm missing something, so help me out.
There are other places where references are "necessary" though (for instance the return value of vector::operator[]), so they couldn't be removed from the language entirely even if you didn't allow them in argument lists.
No, no, I didn't mean get rid of references, or even disallow them, I just think the other poster's favorite usage of references is anything but 'best'. For operators references are a necessity. Like operator overloading, I think references are a feature that should be used with care and that many C++ programmers go overboard using these features simply because they are there.
The only C++ feature I think should be removed is the 'private' keyword. It has just never worked out for me that I could derive from a class and override its functions without having an intimate knowledge of how the base class worked. The 'has-a' relationship seems much better if you want to treat the base class like a black box. Personally I think "private" should mean what "protected" does today, and "protected" should be changed to mean that members can be accessed but not modified. This would fix my other pet peeve, having to write swarms of getFoo() functions just to disuade random doinking with the internal state. But I digress into a dreamland...
And I posted another comment about how I don't find even the readability argument in favor of passing by pointers unconvincing.
Yeah, and I agreed with your caveats (especially that all my blather only applies to C++ references).
It's good rule, and one reason why I think that the proposed someVector += 5, 6; syntax is absolutely awful.
Ugh, what's that supposed to mean? Is that something using the sequence constructor?
However, I think that an exception can be made for the shifting operators and input and output partly because of the very long history that they have, and partly because (to my knowledge) the shifting operators were pretty much invented for programming. +, *, etc. all have meanings we've seen since kindergarden or before; << doesn't. It makes sense, but then it also sort of makes sense for stream operations.
Sure, now it has history, but at the time << had a long history of being only the shift operator. I agree that if one were going to pick an operator to make into the stream operator, that was the best one. I wish they had created a new one, like ~~, but I can think of a couple reasons why that could have been undesireable.
(I know this is a war I can't win, but: I think that printf syntax often looks nicer, but it's harder to learn, a lot harder to understand if you don't know it, and isn't typesafe. You also have issues with how you output with classes because you
The enemies of Democracy are
I've seen advice that addresses this point, and recommends the use of reference parameters for situations in which null is invalid and pointers for when null is valid for this very reason. Sutter and Alexandrescu give this advice for when to pass by pointer and when to pass by reference:
* Prefer passing by (smart) pointer if the argument is optional (so callers can pass null as a "not available" or "don't care" value [the issue discussed above] or if the function stores a copy of the pointer or otherwise manipulates ownership of the argument
* Prefer passing by reference if the argument is required and the function won't store a pointer to it or otherwise affect its ownership.
Hmm, that isn't terrible advice, actually. You don't have to bring up examples of functions that take NULL to mean "don't care", I know of some. time() being the first one that springs to mind, and of course I've written some myself. I would still prefer some syntax that indicates that a value is being passed by reference.
The enemies of Democracy are
Damn, and we used to just use a plain old text file. Why does everything have to be XEverything these days?
XML is a not-particularly-good implementation of a not-particularly-clever idea, whose sole benefit in most cases is that there are libraries to parse it for you. Then again, if your programming language is even slightly good at text processing, you can do enough reading and parsing to handle most configuration files in a line or two of code anyway, and the rest is just overhead.
Or you could just hard-code data that's not really likely to change anyway, and have a much faster, more maintainable program than the guy who wrote more lines to process his XML than there were in the file he was processing. I'm just sayin', y'know, it's a thought.
If you disagree, post your argument. (-1, Overrated) isn't your personal censorship tool for views you don't like.
You don't have to bring up examples of functions that take NULL to mean "don't care", I know of some. time() being the first one that springs to mind
...
Wow, I was actually thinking something along those lines, but I didn't think it was something that simple. I checked out stuff like a couple of the itimer functions, gettimeofday, but didn't see it.
I would still prefer some syntax that indicates that a value is being passed by reference.
I would too, with the caveat that it not be required at call sites for functions that take const references. (The latter I think is necessary because there are a lot of places where it's passed by const reference and it's not logically a reference parameter. In fact, I think if you required notices even at those points you'd be at the C/pointer situation, which, as I said, is hardly better. The downside is it wouldn't be perfect, as there are still mutable members, casting away const, etc.)
For instance, I'm a fan of the C# method:
void swap(ref int a, ref int b) { int t = a; a=b; b=c; }
then
int one, two;
swap(ref one, ref two);
It even goes further with allowing you to specify just out parameters:
void assignFive(out int a) { a = 5; }
then
int one;
assignFive(one);
(Don't ask me why you'd write that, it was just the easiest demo of an out parameter I could think of.)
The latter has the benefit over making the parameter ref that the compiler would complain that you're using an uninitialized variable in the call to assignFive otherwise. (But now it would also complain if assignFive tried to use a before assigning to it, as it assumes that out parameters can be uninitialized.)
Obviously there is a runtime check that didn't exist before, but in situations where one could actually get a null pointer I don't see how changing to references fixes it at compile time. I can only see it in the sense that you can't use new() to assign to a reference and then forget to check for null like you can with pointers, but that's just avoiding the functionality, not fixing the problem. I'm missing something, so help me out.
I guess it doesn't provide nearly the benefit that I was thinking. The only situation where it might is if you would, with the pointer version, explicitly type NULL as a parameter. You can't say foo(*NULL) so can't call the reference version with a NULL reference explicitly.
(The other time it could help is if you had another static analysis tool that was good enough to detect that at the time of foo(*a) it's possible a was null but either doesn't support annotations that foo can't take a null parameter or don't have the ability to annotate foo.)
Ugh, what's that supposed to mean? Is that something using the sequence constructor?
someVector += 5, 6; would be equivalent to someVector.pushBack(5); someVector.pushBack(6);
I'll agree that writing a bunch of pushBacks or however you do it can get annoying, but the drawbacks of the += greatly outweigh the benefit. (And I'm usually a big fan of both conciseness and syntactic sugar)
[I would like to take a time out of this post and say just how wonderful the UndoCloseTab extension is in Firefox; I had typed out this much and accidentally hit ctrl-w instead of ctrl-v (I use Dvorak layout and W and V are adjacent), but UndoCloseTab keeps any form data you've entered. I just discovered this the other day, and the W thing is something that I've always had problems with (I think I found a way to disable the keyboard shortcut, but I forget how), so I'm still excited about its consequences. We now return you to your regularily scheduled slashdot post.]
Sure, now it has history, but at the time
Or even just ~... I can't think of any parsing ambiguities that would create...
If you're using gcc and -Werror, then printf() is actually pretty type safe. Gcc understands printf syntax and can check the arguments (and it is very picky, e.g. it will complain if you reference an unsigned int with %d, or long on a 64-bit machine with %lld) and won't let you pass non-POD types. There's a directive (gcc extension) you can use to tell gcc that a function is printf-like and get the same argument checking on it.
That's true. I was thinking that you'd have to use Lint or some other third party tool to get the checking.
For printing non-POD types, you have basically the same problem with both printf and cout: each class you want to be able to printf/stream needs a function written for it that allows you to do so. For use with printf, you create something like string MyClass::toString(). For cout, you create an operator
There's another, which is that if you're going to write that function in the class, what does it actually do? Call printf directly? Now you're less general than a good ostream operator in C++, because you can't use it for files or standard error. So you have to pass in a file descriptor. But now you're still less general because you can't use it to help construct strings, a la stringstream.
I think pretty much only best way to do it if you want to stick with printf stuff is to make a toString method, and then you can use that as you please. With ostream, you get the ability to make a function that prints to an ostream directly. I don't know if one of these approaches is better than the other; it's possible that you'd usually just want to write toString and have the << operator call that. I've given it some thought and can't come up with a dramatically convincing argument for either method.
(I do think the situation is worse with input though. You can't write a "read from this string" function because then how does the code that ca
For example, you could replace 99% of the type-unsafe macros with templates and const data instances. Or you could use constructors and destructors on your structs to get rid of crap like { foo f; init_foo (&f); ... ; destroy_foo (&f) }. Which is obviously tedious and error prone. The list goes on and on.
Sounds like a hell of a lot of work to address problems that don't arise in other languages.
-jcr
The only title of honor that a tyrant can grant is "Enemy of the State."
Just a note: interface == .h for java. Document all you want, and ship to your customer, along with a crypted jar with the actual binary.
I think I know what you're getting at, but I don't think its quite true.
Interfaces in Java are only used like a .h file once they're compiled. The compiled .class file is what you're actually importing... or rather, the API of that .class file. On the other hand, a header file in C++, IIRC, is inline at compile time as plain text before the compile does anything. Thus, you could include anything text you want.. imcomplete syntactical fragments, for example. In Java, this is not possible. This is essentially the difference between a preprocessor which treats source and includes as text and the Java compiler's treats imports as a way for the compiler to be aware of a pre-compiled API. That is, one happens in the text domain while the other happens in the domain of the compiler's understanding of the parsed source. This is nice in some ways, btu also means you can't do some cool tricks you could do with a preprocessor.
As for the crypted jar file, I'm not sure as I don't use them much. But what I am fairly certain of is that Java uses runtime linking, meaning the actual names of methods and classes is stored in the .class file itself so that they can be linked to the right code loaded from elsewhere by name. So in order for Java's runtime linking, the non-private API of a class must be known to the .class. This is why once you have a .class file, you can run javap against it and get its API. Its just dumping the same information that is used at runtime to match of what one class needs to what another provides.
So, I'd say Java's runtime linking info in a .class file is most similar to what C/C++ header files are used for a good deal of the time, but via a var different mechanism that those includes. Thus, it is much cleaner at doing that job, but weaker at doing everythign else you might do in a header file.
What I started to hate in C++/Java/C# is that there's no easy and standard-conforming way to express complex data 'inline'.
I once worked on a Java programmer (written by a lot of recently C programmers) that had sometime like a Vector of HashMaps, and each HashMap had an element under a a known key that was an Array, and the first item in the array was a Vector of IDs, and the second item in the array was a Map of names to a Vectors where the 1st, 2nd and 3rd items were a crude struct. You couldn't debug crap with this, and even coding was hard unless you had a colorful diagram on your whiteboard explaining what everything meant.
This reminded me a lot of what I used to do with Perl before I started taking advantage of Perl's OO features.
I've often found places where I need to do somethign quick and dirty for a test program and wish I could just use Maps of Arrays rather than defining formal types. But for anything serious, it is much better to just make formal classes for each one. These classes are then types, and which gives not just your language some semantics, but the code you've written now has semantics!
Consider:
(String)((Vector)((Map)((Object[])((Map)vec.get( 0)).get("foo"))[1]).get("email")).get(0)
vs.
customers.getCustomer(0).getContact("foo").getEm ailInfo().getEmailAddresses().getEmailAddress(0)
I'm keeping up just fine, sunshine. Would you care to attempt to make some cogent argument in favor of C++? ('cause you sure haven't yet.)
-jcr
The only title of honor that a tyrant can grant is "Enemy of the State."
Interesting, so what does this "foo" function that returns a "MyObject" do?
XML causes global warming.
Actually, I don't know. /vmlinuz and /dev/hd?? are specified in grub configuration files. I suppose /dev/tty could be specified in the grub configuration file instead. I'm not insane enough to try it though :-).
/dev/tty...
But we're getting seriously offtopic now...
Unless C++0x adds a feature that allows booting from
Don't underestimate the power of The Source
What are you doing such that you need to put constant data into a vector like that? Is there a reason you're not just using an array?
Vectors have more built-in guards against buffer overflows.
One wonders.
XML causes global warming.
>> >> get rid of crap like { foo f; init_foo (&f); ... ; destroy_foo (&f) }.
// access file // have to remember
// access file
// have to remember
// file falls out of scope and destructor calls close
>> >> Which is obviously tedious and error prone. The list goes on and on.
>> Sounds like a hell of a lot of work to address problems that don't arise in other languages.
The problem of remembering to cleanup resources is not contained to just C and C++. It is not just memory, but also files, sockets, database connections, threads, etc.
in C:
FILE* f = fopen("foo", "r");
fclose(f);
in Java:
FileInputStream file = null;
try {
file = new FileInputStream("foo");
} catch (Exception e) {
} finally {
file.close();
}
in C++:
{
fstream file("foo");
}
> Operator overloading is indeed a carnival of confusion that would have been best avoided.
Actually, on the contrary, the entire purpose of operator overloading is to reduce complexity. std::auto_ptr would not be able to hide the memory management semantics from you and still act like a pointer without this feature.
If you do any serious development on any scale, you have problems MUCH bigger to solve then to worry about a tiny semantic. To do any problem solving on a large scale, you need to express and capture your problems as the smallest factors possible, test them in isolation, then scale your usage of that solution. Anything the language can do to hide the fact that you had to solve that problem in the first place will help you keep more important things in your head. So yes, operator overloading works best when the symbols are the natural way you would want to solve a problem, when they are intuitive.
I think one of the main problems with overloading is you can't control precedence, if you could we would probably be writing:
std::cout = "Hello world!" + std::endl;
But if it was implemented that way right now we would be using ()'s all over the place.
C+=2 ?
In other words it is very hard to write automated code browsing tools or refactoring tools for C and C++ because you can't parse a given source file
Some might say that a command like "gcc -E" would solve this, as it runs the preprocessor stage only, creating a file which other tools can parse. However, that's not a real solution, because the preprocessor depends on -D macros set from the makefile / environment-vars / build-script, which may be arbitrarily complex.
As usual, powerful and flexible software has the pitfall that it cannot be sanely analyzed by another program.
I haven't managed to come up with a situation in which you'd want to store so many booleans that you could afford processing power more than extra space, since hard drives and memory are relatively cheap these days.
Classic example is the Sieve of Eratosthenes. Use a byte array and you've multiplied RAM usage by 8. That said, if you really need it, you can probably implement a bit vector in terms of a byte array.
after all you're just calling a function, and add(a,b) isn't much more typing than a + b... right?
At least in Lisp they'd be of the same form: (add a b) vs. (+ a b). Common Lisp fans will be quick to point out that the destiny of C++ and every other similarly high-level language is to reinvent the feature set of Lisp, allegedly poorly.
Yes, many many times. By far, the bulk of my career as a .net, C#, powerbuilder, and
programmer. And for quite a bit of it as a C++ programmer.
Also, visual basic, 5, 6 and
various flavors of SQL.
I am lead of a development team just now, in fact. I have
worked on the committees established to publish coding standards
for a couple of the places I worked.
Most of the coding standards I have run into are more about
formatting and clarity rather than "avoid these language
features".
I dont really see how coding standards fit into this, though.
It is not like Java/VB/C# dont require a coding standard, and
dont allow enough flexibility for your developers to go all over
the map. Not as much, but enough.
But on coding standards. If you have a coding standard,
( and you expect to enforce it ), you have code reviews. If you
dont have those, then some small number will adhere to the
standard, most wont. If you use your coding standards to
subset your language that is your choice. My preference
would be to tell my team to code for maintainablity and
clarity, and be darn sure they understand KISS. But
simple means as simple as possible, but not simpler. And use
the code reviews to educate on language features to avoid,
should any crop up. Except for one guy that came up from VB
who thought that assigning to a character arrary ( pointer )
would copy and reallocate the string, I have not had much
need to do this. I would prefer not to be taking tools out
of my programmers hands.
Personally, though, I dont find C++ to be ridiculous. I find it
to be a very powerful language with a ton of warts. And most of
those warts have been the pain points that lead the developers of
Java and C# to have the language they are today. Without that
learning experience, I doubt those two at least would be where
they are today. But I personally dont care to have my hands
tied behind my back by language designers because there are a
large number of people for whom the tool is a bad choice.
All of that does not mean that I will only use C++, I prefer to
use the best tool for the job, and sometimes that is C++, and
sometimes it is not.
emt 377 emt 4
Well, not for the property thing, I can live without that.
I would kill for a multipass C++ compiler that lets me write classes like C#/Java. With cross module optimisation (LTCG in visual c++), it pretty much needs to do multiple passes anyway, so they might as well have the option.
This would be a major change, so at the same time, I would suggest a tidying of the language to get rid of any syntax hacks (ahem, pure virtual = 0), and anything that's simply for legacy support. I guess you'd end up with a quite different language, which is fine, so why not have profiles like with XHTML (strict, etc), to ease migration?
There are loads of languages I'd like to try, which are going for a lot of the same goals, but they always have a dealbreaker. D looks ok, but then I can't live with forced garbage collection, and there aren't going to be compilers for PS2, Xbox, etc. Therefore I would say that any solution would have to have the possibility of being compiled to current C or C++, like C++ was in the old days.
I want variable-sized stack arrays:
...
void function(size_t size)
{
char array[size];
}
There is no technical reason that this can't be done. Even if you have a type with a destructor instead of "char", there is nothing bad about this. The compiler can store a copy of size for later and iteratively destruct them one by one. That's what would happen anyway if you used new[]. (If there is only one variable-sized array being used in the function, it can actually avoid storing the value entirely because it can deduce it by comparing ebp with esp.) GCC implements this feature already and there are no breaking problems with it.
Another thing C++ needs is a standard implementation of big integers. C# and Java have this. Even Perl has this. It's such a pain when doing cryptography to either reinvent the wheel or use some library with annoying DLL/SO dependencies (GMP).
Finally, someone needs to get on Microsoft's case and force them to implement stdint.h like everyone else has.
Melissa
"Screw Sun, cross-platform will never work. Let's move on and steal the Java language." - Visual J++ Product Manager
Stroustrup writes "This illustrates the most significant proposed C++0x language extension that is likely to be accepted: concepts. Basically, a concept is the type of a type; ..."
Templates brought considerable power to the class idea in C++, but templates are fundamentally a static, compile-time issue, while many things can happen to classes during runtime. For a while now, I've been working on a simulation application (remember when everyone seemed to point to simulation as the major application for C++?) where the type of the input file data elements (e.g. long list of integers, floats, shorts, etc) isn't known until runtime. The simulator uses a pipe and filter architecture, so you'd love to have templates Pipe<D> and Filter<D> where D is the data type, but oooh you won't know that until runtime. And you'd love to make the software future proof for arbitrary types of D. The concepts uh concept discussed in the article look like they could fix this problem. And if they don't, the committee should keep working until they do.
adéu,
Mateu
PS why, when I say the post is plain old text, does <D> still require me to use < and so forth?
"And we're happy here, but we live in fear, we've seen a lot of temples crumble..." - Concrete Blonde
E.g. adding strings and complex numbers both have obvious expected meanings. Writing to a stream is nothing like shifting
Shifting is nothing like being incomprably smaller than another number.... but that's what "<<" means. (And furthermore, multiplication is unrelated to footnoting)
[then an assertation] You just moved to runtime what the compiler could have enforced (as much as anything can be) for you at compile time.
A good compiler can validate many assertions before runtime. There's no reason assert(0) couldn't be flagged by a compiler, and other situations evaluating to assert(0) can be caught by static analysis as well.
Of course, due to the requirement to be backwards-compatible with the C build system, real C++ compilers are rarely good enough to make these fairly easy checks.
operators were pretty much invented for programming. +, *, etc.
In my kindergarten * meant "peek down at the bottom of the page"..
never worked out for me that I could derive from a class and override its functions without having an intimate knowledge of how the base class worked. The 'has-a' relationship seems much better if you want to treat the base class like a black box
Doesn't work. In normal times, when Child is-a Parent, then Foo(Parent*) can be passed either a Child or Parent and operate on it transparently.
For use with printf, you create something like string MyClass::toString(). For cout, you create an operator<< with the right types. The big advantage of cout here is that its interface is part of the standard, so if a class implements it you don't have to guess its name.
cout has multiple speed advantages over printf. First, cout is overall more amenable to optimization, because the compiler knows the types from the typesystem, rather than the program parsing a formatter string at runtime. Second, any toString function you write will probably use a hefty bit of dynamic memory, or be non-reentrant.
Even so, the syntax of printf is nicely more compact, and the speed is not hugely important, so one may wish for a "C++ aware" printf. Such a function could work by adding an additional format specifier (say %P), which indicates that the argument is a pointer to a class derived from PrintfCompatible. PrintfCompatible would have a single pure virtual toString function.
With that in place, you could freely say
printf("My personal fav object is %P\n", &favorite);
no matter what kind of class you had written.
If you're using gcc and -Werror, then printf() is actually pretty type safe. Gcc understands printf syntax and can check the arguments
That goes back to Bjarne's goal of providing user-created systems the same power as native language features. If you write your own class highly resembling cout, it will enjoy all the typechecking the official cout does. But implement your own printf analog, and gcc won't know to check the format string for type information.
(Hypothetically, a compiler could be smart enough to statically analyze the code to my_printf and notice that a "%c" in the string means that the input needs to be safely usable as a char, but that'd be highly ambitious)
had a bit of BASIC experience before moving to C++, and cout is a lot closer to PRINT than printf is (somewhat ironically given the names),
C++0x will finally bring the long-awaited operator" "() feature into C++, so the next version of cout will look even more like the old BASIC PRINT. No more << between variables; just type them out one after another.
I don't think the committee has decided if operator() will be replaced with operator" "() or operator,() yet, though. They've already rejected operator""(), which is a shameful lack of vision.
You seemed to have entirely missed my point about writing image processing software. While I was talking about writing one piece of high-performance code (using templates) that can deal with multiple image formats (and gets automatically inlined by the compiler) automatically, you countered with using prefab Java LIBRARIES (what language do you think THOSE are written in?) or Python (that also uses libraries written in C++ for high-performance image processing).
The mission-critical reference I was making was to Objective-C's runtime binding of functions. Without the compile-time checking you get from C++, Objective C lets you write code that calls functions that might not even exist.
I didn't mention C at all but since you brought it up - it's possible to write far more robust programs in C++, with less code, than C, so people should really prefer C++ over C in almost all cases.
The topic, to get back on topic, is about C++0x, and any discussion of C++ promotes a flamefest. The parent post to this thread was flaming/whining/ranting about some aspect of C++ while neglecting to use any paragraph breaks, and people piled on to the parent post lecturing the dude/dudette about the need for paragraph breaks when posting.
I was trying to point out a parallel between C++ and Slashdot posting -- they are both feature-full and expressive at the risk of making a dumb mistake, and when the dumb mistake is made, people pile on telling you how dumb you are rather than considering whether C++/Slashdot could be more dumb resistant. And when a person dares suggest that something be made more dumb resistant, that suggestion triggers a response that a person is also dumb and a complainer to boot.
For more background on this, I defer to Cooper of "Inmates are Running the Asylum", anything by Donald Norman, and the infamous "Unix Hater's Handbook." There is this culture that any user-interface problems are the fault of the luser and that anyone pointing out such problems is a whining complainer. I was reading a book on Boost, and barely made it into the first chapter on auto pointers when my head started to spin on different flavors of auto pointer and how one worked in one situation but would result in a GP fault in another situation -- geez, Louise, in Java you just have garbage collection and don't have to wrap one's head around such issues. Of course, I am probably mentally deficient for not grasping Boost/C++ auto pointer flavors and I will go through life writing mentally-deficient Java.
Doesn't work. In normal times, when Child is-a Parent, then Foo(Parent*) can be passed either a Child or Parent and operate on it transparently.
True, if you use virtual functions. If that's the goal, has-a won't work. I still think that if you do want your child class to be used 'transparently' you're going to have to be able to access or change the child classes 'private' members. In many cases, anyway.
Even so, the syntax of printf is nicely more compact, and the speed is not hugely important, so one may wish for a "C++ aware" printf. Such a function could work by adding an additional format specifier (say %P), which indicates that the argument is a pointer to a class derived from PrintfCompatible. PrintfCompatible would have a single pure virtual toString function.
No, I don't wish for that. It's unnecessary. To make my objects 'printf compatible' I give them a function which returns a string, and use %s in printf. Actually it returns a std::string, which is nicer than returning a char* for a lot of reasons.
Thus it looks like this: printf("%s", someObject.toString().c_str())
So reentrancy isn't a problem. Dynamic memory still is. I'm not certain the room for compiler optimization is that large (my off-the cuff guess is avoiding branch mispredicts by avoiding the indirect branch of a case statement is the most help). I'd be interested to compare the performance of cout and printf, with and without non-POD types. For printing to a console or other such, I highly doubt it matters. But for buffered file io or other in-memory operations it may.
But implement your own printf analog, and gcc won't know to check the format string for type information.
If your printf analog uses the same format specifiers as printf, then it can with a gcc-specific directive. In the general case though, yeah, varargs lack type safety.
The enemies of Democracy are
"You seemed to have entirely missed my point about writing image processing software. While I was talking about writing one piece of high-performance code (using templates) that can deal with multiple image formats (and gets automatically inlined by the compiler) automatically, you countered with using prefab Java LIBRARIES (what language do you think THOSE are written in?)"
Mostly Java, actually. This wasn't originally the case, but as Java's performance has increased, various parts of its core libraries have been rewritten in itself. The primary reason for this is to make porting it to other platforms easier: the less non-java code there is, the easier the system is to bootstrap with only a Java compiler.
"or Python (that also uses libraries written in C++ for high-performance image processing)."
Most Python libraries are written in C because that is what Python binds to. There are some C++ ones (usually with C "wrappers"), but then there are some written in other compiled languages as well.
"The mission-critical reference I was making was to Objective-C's runtime binding of functions. Without the compile-time checking you get from C++, Objective C lets you write code that calls functions that might not even exist."
You are missing the fact that Objective-C is perfectly capable of using static typing if required. You simply declare a pointer to a type directly as you would in C, e.g. "MyClass *aClass;", and voila! Any attempt to send a message isn't a member of "MyClass" on "aClass" will result in a compile-time warning. Dynamic types are therefore an option that you can use or not use, much like many C++ features. Note also that for those times when one wishes to avoid the overhead of the message dispatch system, Objective-C allows methods to be directly called by address. This is as fast as calling a C function by address (because that it what it is doing).
I'm not going to change your sheets again, Mr. Hastings.
Shifting is nothing like being incomprably smaller than another number.... but that's what "
Just like calculus means different things to a dentist and a mathematician, the C/C++ programming language is a specific field with its own jargon and the 'obvious meaning' of an overloaded operator should be derived from that. Obviously. Since 1970-ish, << has meant bitwise left-shift in the realm of the C programming language and its derivatives.
Perhaps a better way to put it would have been to say that a programmer should be able to intuit the behavior of an operator based on the behavior of that operator on all other types.
The enemies of Democracy are
Interesting, so what does this "foo" function that returns a "MyObject" do?
As an Real Programmer would know, it snafucates the enabalizer.
The enemies of Democracy are
someVector += 5, 6; would be equivalent to someVector.pushBack(5); someVector.pushBack(6);
:P
:)
/. used to be full of cool geeky coding discussions like this one?
I thought from the article that it would have to look like someVector += {5,6}, like it would if 5,6 was intended to be a normal array initializer. That doesn't seem so bad. That is what I would expect array addition to do -- concatenate two arrays.
The main problem with 'vector' and operators as far as I'm concerned is the name. Absolutely terrible name for "better array". While a (math) vector is an array, an array isn't necessarily a vector. I would expect to be able to do a vector dot product with '*', but of course I can't. And then if you want to make a useful mathematical vector class, the name is already taken.
I think pretty much only best way to do it if you want to stick with printf stuff is to make a toString method, and then you can use that as you please.
Yeah, like I said, that's what I do. printf("%s", myObject.toString().c_str()) is the kind of thing you'll see in my code.
I do think the situation is worse with input though. You can't write a "read from this string" function because then how does the code that calls it doesn't know how much to read from the keyboard before it calls it; if it reads too little, the object can't be built, but if it reads too much it's extracted too much from the stream.
Serializing non-POD types from keyboard input is evil.
But yeah, this is more difficult. To solve the problem, the interface would have to do two things: tell the caller how many bytes it read from the string, and second tell it if there were insufficient bytes to create the object. The second you can do either by returning an error code like pre-glibc2 snprintf(), or better by returning how many bytes the function -would- have read if there were enough, like post-glibc2 snprintf(). Returning the number of bytes needed being more difficult if not impossible to implement in every case.
I'm not a big fan of plain-ol text serialization of objects though. If the objects are complex, then the format should be structured (like xml or length encoding) such that the program -can- know how much data is intended for each object.
I had a bit of BASIC experience before moving to C++, and cout is a lot closer to PRINT than printf is (somewhat ironically given the names), so that's my theory as to why I almost always use cout.
*shudder* I have a lot of BASIC experience pre-dating my move to C, which pre-dated my move to C++ by several years. I never made a connection between PRINT and cout, but it could be that my subconscious is rejecting anything related to those long, dark years of GW-BASIC.
Heh. Remember when
I would like to take a time out of this post and say just how wonderful the UndoCloseTab extension is in Firefox
I'll check it out. I use a dvorak keyboard, but have never had that problem (but I tend to be mouse-driven when using a browser anyway).
The enemies of Democracy are
I thought from the article that it would have to look like someVector += {5,6}
:P
/. used to be full of cool geeky coding discussions like this one?
;-))
That's a separate proposal. I don't know about +=, but I know that at least they're looking at ways to initialize vectors with arrays.
The main problem with 'vector' and operators as far as I'm concerned is the name. Absolutely terrible name for "better array". While a (math) vector is an array, an array isn't necessarily a vector. I would expect to be able to do a vector dot product with '*', but of course I can't. And then if you want to make a useful mathematical vector class, the name is already taken.
I can't find any information, but it makes me wonder how long the term 'vector' has been used for stuff like that. I know at least Java too has the term, but it could have borrowed it from C++ for all I know.
(As to your last point, that's why the standard committee introduced namespaces!)
I'm not a big fan of plain-ol text serialization of objects though. If the objects are complex, then the format should be structured (like xml or length encoding) such that the program -can- know how much data is intended for each object.
That's true; if you used XML or something you could read out the right amount before calling the object's function. I hadn't thought of that benefit of using that sort of data format.
it could be that my subconscious is rejecting anything related to those long, dark years of GW-BASIC.
Ah, see, most of my basic experience was with QBASIC, which, as much as I could tell with the little GW experience I had, is a whole lot easier to use.
Heh. Remember when
Every now and again they pop up again.
(Now we need someone with an ID of like 17 to pop up and say "do I remember? what do you think?"
I'll check it out. I use a dvorak keyboard, but have never had that problem (but I tend to be mouse-driven when using a browser anyway).
Ah. That's a mistake I do incessently. And it's really obnoxious because usually if you're pasting something you're in a nice discussion like this, and often you've typed out quite a bit...
Thus it looks like this: printf("%s", someObject.toString().c_str())
To many programmers, the need to use those additional 16 characters everyplace you print something is itself symptomatic of a problem, and cout is valued for alleviating it.
So reentrancy isn't a problem. Dynamic memory still is
If you're willing to make toString non-reentrant, it has a much lesser need to use dynamic memory (especially if it returns a char* instead of a str::string, which you'd want to do anyhow if speed was important)
And then there are those of us who actually utilize our brains and realize that if a statement cannot be proven, it is not worth making.
There are many things that are true that cannot be proven. There are many decisions one must make where one cannot prove what the best solution is. There are many things that are simply matters of opinion, which intelligent people can discuss reasonably, realizing you cannot "prove" your position.
Then there are idiots like you, who failed 1st grade "fact or opinion?" exercizes. No, really. This whole thread is little more than a discussion of opinions on coding style and if you think your 'opinion' is 'fact' then you are indeed a retard of the highest order.
That's just my opinion though, lol.
The enemies of Democracy are
Never used (most) of them, so I didn't comment on them.
But seriously, Python?!?!?! It's a spacing-dependent scripting language. Just because it's been used for bigger problems than it was originally intended for does not mean it's suddenly a general-purpose language.
I'm really curious as to why you lump in functional languages with your list of "type safe" languages. The very definition of functional languages is that they generalize implementations instead of defining type-specific implementations.
If removing type concepts and support are your idea of making something type-safe, you should love LISP. You're down to two types: atom and list. And technically the former is just a member of the latter, so you've only got one "complex" object to deal with. :p
I do not fail; I succeed at finding out what does not work.
Whether a language is functional or imperative says nothing about its type system. There are imperative languages that are typed much like Lisp, and there are functional languages that are typed much like Ada. However, the vast majority of research into type safety and types in general occurs in functional languages. See Benjamin Pierce's Types and Programming Languages, which uses ML, or almost any paper in the field. It's also worth looking at Microsoft Research's work in types (usually tested in their Cw language, though C# 3.0 looks to be inheriting some of ML's type features.)
Do you have any real experience programming with C++ or any real experience programming at all?
Do you have any real experience with software engineering, or have you just memorized enough of the minutia of a horrificaly complex language to think you're hot stuff?
I've been writing code in many, many languages since 1977, and doing so professionally since 1982. I once considered C++ an improvement over C, but I revised that opinion once I saw Objective-C, which made me understand just how badly Stroustrup had botched his attempt to add object orientation to C.
As a specific example, C++ gives you RAII which when used properly helps avoid all kinds of resource finalization errors.
Thrillsville. You're a fan of side-effects. May you spend the rest of your career sorting out static constructors executing before main().
For an encore, want to tell me how templates can save loads of time writing code, which you then lose debugging the fucking templates?
I could provide (as others have) more examples of C++ features (many of which can be used alone) which make C++ often a good replacement for C
No, you can't. You can trot out yet another of the C++ misfeatures that people like you are so proud of, and crow about how they solve issues that I left behind a decade ago.
-jcr
The only title of honor that a tyrant can grant is "Enemy of the State."
Well, the heat was on the other day and I must admit I got carried away. In the same way as others have critisized C++ while never having done anything serious with it I was critisizing on the rails framework, knowing to little about it. In retrospect, it actually reduces the value of my other comment - which does hold a lot of truth as for the other part.
;-)
The only thing with Ruby is that I fail to see why we would need yet another language - except maybe to introduce object orientation in scripting languages. But I'm not so much in favor of scripts in the first place; configuration files and good software are a better alternative imho. But that's another discussion.
I do seem to have drawn attention with my rant though...
And what if there's nothing behind the door until it is being opened?
> You have to remember who you're dealing with here. Many of Slashdot's commenters are kids who have dabbled in scripting or perhaps...
/. may become tomorrow's next generation of programmers. That's what concerns me if now they turn away from C++.
...)
Yes, that is true, however:
- today's script kiddies on
- companies use internet forums as a source of marketing research and can in the long run - wrongfully - get the idea that mature languages like C++ haven't got it anymore and as a result no longer produce software for it (such as compilers, editors,
- IT managers, often having no clue at all about the programming language anymore may use such forums as a source of information to select the language in which to develop.
etc.
I think it is usefull to provide a counterweight in the discussion in order to protect a beautiful language that too few people calling themselves programmers bother to master.
> Andrei's Alexandresu's "Modern C++ Design" demonstrates these features well - that book is just mind boggling
Amen to that. This is the future of programming languages. Nowadays, OO is being taught, in a few years time, aspect oriëntation and policy-based design will be the norm.
The only thing I wish to add is that my rant about Ruby (on or off rails) being retarded was exaggerated. What I should have said is that I don't see why we need another language.
And what if there's nothing behind the door until it is being opened?
Well, I stick by my comment about a great deal of Slashdot posters. Many are poorly informed about programming. Most don't work as programmers. I wasn't really referring to just "script kiddies" by that. Basically, "hard" things that deviate from the Unix norm (C and Perl, basically) are denigrated. C++ has a difficult syntax, exploits some of the more nether regions of object oriented design, and does not have a Unix-friendly history. Therefore, it is "bad", even to people whose total C knowledge amounts to "Hello World".
;)
I agree about Ruby being Yet Another Language that tries to occupy a niche already filled by Python. That said, there is a great deal to be said for virtual machine-based languages. Python is just awesome. It boils down to requirements, and balancing the demands of rapid deployment with application speed. A VM language with a nifty, list-based syntax (I've heard it said that Python is Lisp with conventional syntax) is just the ticket if app speed is not the highest priority, but time to market is. Then you can profile what you've done and touch up the hot spots with custom modules written in C or C++, if you need to. It works quite well.
I too regard C++ as a beautiful and deep language whose possibilities are only just being explored.
All that said, I work in a startup with nine programmers. What we're doing with Python may allow us to succeed. If we were using a more time-costly language like C++, we would fail. So everything has its place
Probably this : http://www.digitalmars.com/d/property.html which is incomparably more elegant than the C way.
Those are useful features, but the most important thing C++ needs is a notion of safe modules, analogous to what C# has.
But, frankly, to me, C# is what C++ should be anyway. The only thing that is annoying about C# is its Microsoft connection and the concerns that causes.
A major difference that I can think off the top of my head is that C++ concepts are not "hard-wired" into the language. People can create non-standard extensions to these concepts and it will "just work".