C/C++ What are the new features in C++0x and how do they work?

  • Thread starter Thread starter Grep
  • Start date Start date
  • Tags Tags
    Tires
Click For Summary
The discussion focuses on the completion of the final draft for the next version of C++, known as C++0x, and the features available in the GCC compiler, particularly version 4.6. Key highlights include the introduction of initializer lists, ranged for loops, and the auto type, which simplify code and enhance readability. Users shared their experiences with installing GCC and compiling programs, emphasizing the ease of using new features like lambda expressions and tuples.The initializer list feature allows for straightforward initialization of containers, while ranged for loops provide a cleaner syntax for iterating through collections. The auto keyword simplifies type declarations, reducing verbosity. Other notable features discussed include enum classes, new array types, and enhanced time functionalities.Participants expressed excitement about these improvements, although some raised concerns about the lack of scientific programming support in C++0x and the potential obsolescence of certain Boost libraries.
  • #31
Jocko Homo said:
I am very curious to know how on God's green Earth it could "appear" as if I'm talking about the auto keyword. Can you please explain this to me?
Because it didn't look like you were talking about the for keyword. I still don't understand your objection.

You don't have to use Boost in particular. What Boost demonstrates is that you can do range-based for loops (as I now know they're called) with the language already. You didn't have to resort to language hacking...
In the eyes of many, using the preprocessor for anything but the standard one-time include guard (#ifndef NAME/#define NAME) and #include statements is language hacking. Abuse of the preprocessor is standard fare for the IOCCC. For your amusement / disgust, here's a winning IOCCC entry written by Jim Hague back in 1986 that translates ascii to Morse code, with the ascii text read from standard input:
Code:
#define	DIT	(
#define	DAH	)
#define	__DAH	++
#define DITDAH	*
#define	DAHDIT	for
#define	DIT_DAH	malloc
#define DAH_DIT	gets
#define	_DAHDIT	char
_DAHDIT _DAH_[]="ETIANMSURWDKGOHVFaLaPJBXCYZQb54a3d2f16g7c8a90l?e'b.s;i,d:"
;main			DIT			DAH{_DAHDIT
DITDAH			_DIT,DITDAH		DAH_,DITDAH DIT_,
DITDAH			_DIT_,DITDAH		DIT_DAH DIT
DAH,DITDAH		DAH_DIT DIT		DAH;DAHDIT
DIT _DIT=DIT_DAH	DIT 81			DAH,DIT_=_DIT
__DAH;_DIT==DAH_DIT	DIT _DIT		DAH;__DIT
DIT'\n'DAH DAH		DAHDIT DIT		DAH_=_DIT;DITDAH
DAH_;__DIT		DIT			DITDAH
_DIT_?_DAH DIT		DITDAH			DIT_ DAH:'?'DAH,__DIT
DIT' 'DAH,DAH_ __DAH	DAH DAHDIT		DIT
DITDAH			DIT_=2,_DIT_=_DAH_;	DITDAH _DIT_&&DIT
DITDAH _DIT_!=DIT	DITDAH DAH_>='a'?	DITDAH
DAH_&223:DITDAH		DAH_ DAH DAH;		DIT
DITDAH			DIT_ DAH __DAH,_DIT_	__DAH DAH
DITDAH DIT_+=		DIT DITDAH _DIT_>='a'?	DITDAH _DIT_-'a':0
DAH;}_DAH DIT DIT_	DAH{			__DIT DIT
DIT_>3?_DAH		DIT			 DIT_>>1 DAH:'\0'DAH;return
DIT_&1?'-':'.';}__DIT DIT			DIT_ DAH _DAHDIT
DIT_;{DIT void DAH write DIT			1,&DIT_,1 DAH;}


With that said, yes, it does use a macro and this is less than ideal. However, it is a well behaved macro and it's not as if macros aren't an integral part of C++. Hell, the entirety of C++ libraries are implemented using the preprocessor...
The entirety of C++ libraries are implemented using the preprocessor? Where did you get that idea? Most of the C++ library is in the form of templates. The preprocessor doesn't know beans about templates.
 
Technology news on Phys.org
  • #32
Hurkyl said:
The point of a practical programming language like C++ is to write programs, not to strive to achieve purity of form (if we could even agree on what that should be). This update was meant to fix shortcomings in the language; the overly verbose and redundant "for loop that iterates over a range" syntax was one of those shortcomings.
You're assuming that C++ is a practical programming language...

I can understand sacrificing "purity of form" for a practical advantage but... again, the language has already made too many sacrifices for "purity of form" for this change to not seem odd, especially considering the existence of alternative like BOOST_FOREACH. Going back to my constructor example, there's no known code, template or macro madness that can fix or even alleviate the redundancy of constructor declaration yet they didn't bother to update that... Obviously "purity of form" means something to the *committee...
 
  • #33
D H said:
How? The old syntax for for loops still works. for is now overloaded. If you don't like the new syntax, don't use it.
I didn't say it broke old code. C++0x was carefully design not to. I'm saying it's breaking old values of C++, like not enforcing a particular convention...

Where? I don't get your objection.
I'm not sure to what you're referring with the word "where."

It's very unlike C++ to enforce certain identifier names to be used with built-in language constructs like for loops...

It's hard to come up with an analogy that demonstrates how weird this is but it's a little like having while loops being able to do naked object evaluations as long as they provide a "do_while" method that returns a boolean, like so:
Code:
class Foo {
    bool do_while() { return true; }  // infinite loop...
};

int main() {
    Foo foo;
    while (foo) {
        // should probably do something...
    }
}
Wouldn't it be weird if C++ started doing things like this?
 
  • #34
Is it worth it to keep with conventions if they limit the convenience of using the language? Consistency is impossible in a complete language.
 
  • #35
D H said:
Jocko Homo said:
I am very curious to know how on God's green Earth it could "appear" as if I'm talking about the auto keyword. Can you please explain this to me?
Because it didn't look like you were talking about the for keyword. I still don't understand your objection.
That doesn't answer my question... at all...

Obviously it didn't appear to you that I was talking about for loops. I asked how didn't it appear so? What did I specifically say that made you rule out the possibility that I was talking about for loops and rule in the possibility that I was talking about auto? I'm baffled by this and I'm curious to see the train of logic...

The entirety of C++ libraries are implemented using the preprocessor? Where did you get that idea? Most of the C++ library is in the form of templates. The preprocessor doesn't know beans about templates.
You had to use the preprocessor to use template libraries in your code with the use of the include directive, which is basically just one giant macro. If you happen to have a text file named "include_me.idontcare" and it contained this:
Code:
for (i = 0; i < whatever; ++i) {
    printf("%i\n", i);
}
...and you compiled this code:
Code:
#include <stdio.h>

int main() {
    int i;
    int whatever = 4;

#include "include_me.idontcare"
}
...the compilation will succeed and the executable will run! ...yet we all recognize that this code is terribly Wrong. Why? Because it's a poorly behaved macro... yet the include directive is the underlying mechanism of C++ library implementation. It's the reason we put up with pre-compiled headers and all that jive...

There's no getting around how integral a part of C++ the preprocessor is so its use can't be shunned that badly. All you can do is ask that people write well behaved macros and good programmers try to do just that...
 
  • #36
TylerH said:
Is it worth it to keep with conventions if they limit the convenience of using the language? Consistency is impossible in a complete language.
It depends on what you mean by "consistency." The reason I bring up range-based for loops is because, before this change, C++ was consistent in its lack of identifier enforcement. To say that this is impossible is an exaggeration...

Is it worth it? The committee seems to think so. I guess I tend to agree although I suppose I'm somewhat conflicted on the issue...
All I wanted to point out was that it's a little wrong...
 
  • #37
Jocko Homo said:
It depends on what you mean by "consistency." The reason I bring up range-based for loops is because, before this change, C++ was consistent in its lack of identifier enforcement. To say that this is impossible is an exaggeration...
It's not enforced. You can implement them if you want your class to work with the new for loop, just like you have to implement operator+ if you want your class to work with the + operator.

Impossible is far from an exaggeration. http://en.wikipedia.org/wiki/Gödel's_incompleteness_theorems#First_incompleteness_theorem You can either be complete or consistant. C++ chose to strive for completeness, apparently.
 
  • #39
Jocko Homo said:
It depends on what you mean by "consistency." The reason I bring up range-based for loops is because, before this change, C++ was consistent in its lack of identifier enforcement.
Also, before c++0x, the language was consistent in its lack of range-based for loops, its lack of lambda expressions, its lack of variadic templates, its requirement for the type of a variable to be explicit at declaration, ...

Seriously, I find this an odd thing to get worked up over. I honestly don't understand how someone can find this important or even merely notable. Doubly so, given the slew of operator foo functions that various language constructs invoke.

It's also not like begin and end came out of nowhere -- this usage had already been established in the standard libraries.
 
  • #40
TylerH said:
It's not enforced. You can implement them if you want your class to work with the new for loop, just like you have to implement operator+ if you want your class to work with the + operator.
That's really not a fair comparison...

You obviously have to implement something to get your containers to work with range-based for loops but if you want these new loops, you do have to use certain identifier names, which is weird. Before, it didn't matter what aspect of the language you used, you never had to do this. This has changed...

Your operator comparison makes no sense. That's like trying to compare what I'm saying to the fact that, in order to use while loops, you have to test a condition. Yes, you have to do certain things to do certain other things. It's hard to get around that. How is operator overloading the same as enforcing identifier names?

Impossible is far from an exaggeration. http://en.wikipedia.org/wiki/Gödel's_incompleteness_theorems#First_incompleteness_theorem You can either be complete or consistant. C++ chose to strive for completeness, apparently.
In programming, when people refer to "completeness," they're usually referring to Turing completeness. I'm trying to give you the benefit of the doubt (something you didn't appear to give me!) but I'm really not sure how Gödel's incompleteness theorems apply to programming languages. We're not proving theorems with our languages and "consistency" in this context is not referring to the uniformity of function or behavior. Could you please elaborate?
 
  • #41
Hurkyl said:
Also, before c++0x, the language was consistent in its lack of range-based for loops, its lack of lambda expressions, its lack of variadic templates, its requirement for the type of a variable to be explicit at declaration, ...

Seriously, I find this an odd thing to get worked up over. I honestly don't understand how someone can find this important or even merely notable. Doubly so, given the slew of operator foo functions that various language constructs invoke.
I wouldn't characterize my attitude as "worked up." Is that what it looks like to you?

None of the new features you mentioned enforce identifier names on the programmer. Also, operator overloading is not the same thing as identifier enforcement...

It's also not like begin and end came out of nowhere -- this usage had already been established in the standard libraries.
They're established conventions in the standard libraries but that's all they were. Previously, the C++ compiler knew nothing of the standard libraries. They were completely divorced. You could delete them off your drive or even replace them with something else and still compile code just fine...

For example, I could do a search and replace for all instances of "begin" and "end" and replace them with "beginner" and "endorino" respectively and everything will work exactly the same because C++ never enforced identifier names on the user. Everything was user defined convention...

Now, in C++0x, if you did this and your code used range-based for loops, it would curiously break. That's weird, no?
 
  • #42
Jocko Homo said:
You had to use the preprocessor to use template libraries in your code with the use of the include directive, which is basically just one giant macro.
That is nonsense. #include and #define are very different beasts. Macros are what #define creates, not #include. Conflating #include and #define is trolling. BOOST_FOREACH is a macro, something to be eschewed. Many people / many programming standards deem macros to be so inherently bad that they should never, ever be used, even something as simple as NULL. The vast majority of the C++ and Boost libraries are in the form of templates, which are very useful things.

Jocko Homo said:
I wouldn't characterize my attitude as "worked up." Is that what it looks like to you?
That is exactly what it looks like to me. You are trying to create an issue where the only issue is that a number of languages have this exact feature and the current C++ does not. This is an incredibly compact and rather handy capability. Yes, it may be a bit of syntactic sugar, but it is sweet ...

I don't get your issue at all with current C++ not saying anything about the semantics of identifiers. It most certainly does! You raised two examples of where it does exactly that: constructors and destructors. The existing standard has quite a bit to say and semantics of constructors and destructors.
 
  • #43
Jocko Homo said:
That's really not a fair comparison...

You obviously have to implement something to get your containers to work with range-based for loops but if you want these new loops, you do have to use certain identifier names, which is weird. Before, it didn't matter what aspect of the language you used, you never had to do this. This has changed...

Your operator comparison makes no sense. That's like trying to compare what I'm saying to the fact that, in order to use while loops, you have to test a condition. Yes, you have to do certain things to do certain other things. It's hard to get around that. How is operator overloading the same as enforcing identifier names?
I've already explained how they're related. They're related in how they are both required for an optional feature. How else could it be done? Is it only the fact that they require a specific symbol name(begin and end) your only complaint? If so, what alternative would you propose, and why is it better?

Jocko Homo said:
In programming, when people refer to "completeness," they're usually referring to Turing completeness. I'm trying to give you the benefit of the doubt (something you didn't appear to give me!) but I'm really not sure how Gödel's incompleteness theorems apply to programming languages. We're not proving theorems with our languages and "consistency" in this context is not referring to the uniformity of function or behavior. Could you please elaborate?
It applies in that the language can either be consistent in functionality or complete in functionality. You're arguing for consistency; I'm saying completeness is just as good.
 
  • #44
TylerH said:
It applies in that the language can either be consistent in functionality or complete in functionality.
If you're going to continue down this line of thought, you need to make a connection to Gödel's theorem more substantial than using homonyms of some of the words involved.
 
  • #45
Jocko Homo said:
For example, I could do a search and replace for all instances of "begin" and "end" and replace them with "beginner" and "endorino" respectively and everything will work exactly the same because C++ never enforced identifier names on the user.
Your experiment wouldn't work if you replaced "operator+" with "plus", or of you replaced "int" with "integer".
 
  • #46
D H said:
That is nonsense. #include and #define are very different beasts. Macros are what #define creates, not #include. Conflating #include and #define is trolling. BOOST_FOREACH is a macro, something to be eschewed. Many people / many programming standards deem macros to be so inherently bad that they should never, ever be used, even something as simple as NULL. The vast majority of the C++ and Boost libraries are in the form of templates, which are very useful things.
Just when I thought I was walking away from The Twilight Zone...

I mean... "trolling..." really?

I started by reminding us all that the include directive, which is necessary for library implementation, is a preprocessor function and has nothing to do with C++ syntax. Remember this?
D H said:
The entirety of C++ libraries are implemented using the preprocessor? Where did you get that idea? Most of the C++ library is in the form of templates. The preprocessor doesn't know beans about templates.
I compared them to macros because... well, they're similar. I don't see how pointing this out is trolling but if you really feel this way then you should press the "report" button beside my post...

The include directive is a macro in the general sense and do behave similarly to C++ macros. I even gave a detailed example of what I meant. You deny my claim but you gave no specific argument other than that they use different keywords and declaring by fiat that they are "different beasts." Can you please be more specific than this?

Hey, you never did explain how you concluded that I must have been referring to the auto keyword instead of for. You're pretty evasive...

That is exactly what it looks like to me. You are trying to create an issue where the only issue is that a number of languages have this exact feature and the current C++ does not. This is an incredibly compact and rather handy capability. Yes, it may be a bit of syntactic sugar, but it is sweet ...
Now that I think about it, I am enjoying this thread so, I guess in that sense, I'm getting worked up. It's just that Hurkyl made it sound like I was upset or something...

A number of languages don't have the values and priorities of C++. Languages that have range-based for loops, like Python or Ruby, are high level languages. They know nothing about the hardware they run on. C++, on the other hand, is a low level language. It's crazy how much C++ knows about the hardware. It's almost assembler language!

...not that that's the issue here. I just wanted to point out that different languages have different goals and values. Iterating over containers without the verbosity of C for loops (which is really what they are) is nice but how it was done is rather uncharacteristic of C++...

I don't get your issue at all with current C++ not saying anything about the semantics of identifiers. It most certainly does! You raised two examples of where it does exactly that: constructors and destructors. The existing standard has quite a bit to say and semantics of constructors and destructors.
I'm having trouble understanding what you mean in this paragraph here but I'll take a guess and run it. This is another example of how a little specificity might have been helpful...

C++ does force you to declare your constructor and destructor with the same name as your class but it did not dictate what the name of your class should be: only that they match. This is in stark contrast to range based for loops where you must declare your iterator functions to specifically "begin" and "end." That's it. Otherwise, they're not iterators. Not even "rbegin" and "rend" work...
 
  • #47
TylerH said:
I've already explained how they're related. They're related in how they are both required for an optional feature. How else could it be done? Is it only the fact that they require a specific symbol name(begin and end) your only complaint? If so, what alternative would you propose, and why is it better?
That's a good question. I think someone earlier in this thread mentioned a range-based for loop implementation made using just the previous C++ specification. I think it was part of the Boost library...

Kidding aside, I'm not sure that BOOST_FOREACH is really any better but I do find it very interesting that such an implementation can be done without altering the language...

I'm really not sure what they could have done if they wanted range-based for loops built into the language... which is probably why they tolerated this change but I'm sure there were some people on the committee who cringed as much as I did...

It applies in that the language can either be consistent in functionality or complete in functionality. You're arguing for consistency; I'm saying completeness is just as good.
In regards to Gödel's incompleteness theorems, given any axiomatic system sufficiently powerful enough to describe the natural numbers, "consistent" means that there exists no true statement whose negation is also true, and "complete" means that every true statement in said system is provable.

Can you see why I still can't see the application?

Okay, try answering this. If C++ was consistent before C++0x then, by your understanding, it wasn't "complete." Can you give an example of its lack of completeness?
 
  • #48
Hurkyl said:
Your experiment wouldn't work if you replaced "operator+" with "plus", or of you replaced "int" with "integer".
I'm not sure what point you're trying to make here. If I replaced "{" with "(" then my experiment would also not work but I don't place special meaning to that fact...

"int" is a keyword. It has special meaning which is why you can't simply replace it with an identifier. "operator +" is an operator. It also has special meaning which is why you can't simply replace it with an identifier. If you use range-based for loops then "begin" and "end" also have special meaning... despite they not being keywords... Instead, they're identifiers that you may or may not use... except in range-based for loops where you'd better be using them!

Now, BOOST_FOREACH also requires the existence of a "begin" and "end" method for non-built-in types but, because it's not part of the language, you can change this as a programmer if need be. In fact, it happens to be extensible!
 
  • #49
Sorry, been busy for the last little bit and haven't had time to participate.

Jocko, I fail to see a problem in ranged for that warrants this level of discussion.

Is it a nice feature that makes code clearer? Yes. Is it likely to cause problems/bugs in code? No. Is there a problem associated with adding support for it in your own lists? No.

In short, no problem. It's a fine feature and I'm glad they added it.

Wish this whole digression could be moved to it's own thread and not take up space in this one. Sorry, but it seems rather pointless to me.
 
  • #50
Jocko Homo said:
"int" is a keyword. It has special meaning which is why you can't simply replace it with an identifier. "operator +" is an operator. It also has special meaning which is why you can't simply replace it with an identifier. If you use range-based for loops then "begin" and "end" also have special meaning... despite they not being keywords... Instead, they're identifiers that you may or may not use... except in range-based for loops where you'd better be using them!
I don't see why you think it's strange. The identifier int has a special meaning. The language designers decided programmers aren't be allowed to shadow it, so they made it a keyword. The identifier begin has a special meaning. The language designers decided not to forbid programmers from shadowing it, so it's not a keyword.


In fact, it happens to be extensible!
If this page resembles what will go into c++0x, so is the version in the standard, by overloading the (non-member) functions begin and end.
 

Similar threads

  • · Replies 22 ·
Replies
22
Views
3K
  • · Replies 5 ·
Replies
5
Views
3K
Replies
20
Views
2K
Replies
12
Views
2K
Replies
89
Views
6K
  • · Replies 6 ·
Replies
6
Views
12K
Replies
10
Views
2K
Replies
5
Views
2K
  • · Replies 23 ·
Replies
23
Views
2K
  • · Replies 17 ·
Replies
17
Views
2K