> - constextp
> A constexp function is in fact a "pure" function, i.e. without side-effects, only the keyword is
> misleading :-). What’s the purpose of heaving constexp on the default constructors in many library
> classes? (It allows construction of e.g. an *empty* shared_ptr object.) Esp., why the constexp
> is used only for the default constructors?
"constexpr" is not a misleading term for pure function. It expresses the notion that a funtion can be
evaluated at compile time. This happens to imply that constexpr functions that are not constructors
are pure. I'd say that constexpr is mostly useful for non-default constructors, but that not having
default constructors also would be silly.
> - "Overcomplication"
> Though in general I like the C++0x proposal, in several cases (mostly discussed above) I still feel
> that the proposal is "overcomplicated".
A standard has to serve many user communities and adress many "worries" (real or imagined). This implies
overcomplication from every single point of view.
> As an (counter-)example take "constexp". The academician you cite in your article was right when
> asking "Why don’t you just provide a full compile-time interpreter?" I think that one day this
> interpreter becomes a reality and requested feature. But you are right too that we don’t need
> the full interpreter now, because we’re trying to solve a much more modest problem. And this
> is IMO the correct approach – do not introduce a feature unless you know that you need it.
A full interpreter - even if we wanted it - is beyond today's technology, so the academic's
question was (eventhough he didn't realize it) purely academic. Apart from that, I think that it is
not a bad thing to have the compile-time features a bit restricted to minimize confusion in the
very-hard-to-debug compile-time context. If "you" disagree, please note that constexpr is Turing
> On the other side, there are e.g. attributes. A very general and complex syntax has been developed.
> And now we have the syntax, and do not know what to use it for. Very few attributes have been
> added to the specification, and they still use only a very small part of what the syntax allows.
> This is what I call the "overcomplication". If we didn’t have such big ambitions, the syntax
> could have been much simpler and more readable (e.g. similar to the Microsoft’s C++/CLI attributes).
I think that the [[ ... ]] syntax is simpler and more general than Microsoft's and GNU's syntaxes.
It is also likely to become a menace as a variety of people take advantage of it to provide odd and
> another language complication to an already complicated language
Well, the language can be used in a fairly uncomplicated way to solve uncomplicated problems. For many usual use cases, though C++ is a more 'complicated' language than C, a C++ program (from the perspctive of the programmer who wrote it) tends to be far less complicated than an equivalent C program.
This paper is instructive: http://www.research.att.com/~bs/new_learning.pdf
C++ programs are far less complicated to write correctly than equivalent C programs because of the presence of libraries. The language can be far easier to learn and use, without loosing its expresive power and efficiency, if there are good libraries available to programmers. A powerful general purpose programming language that is easy to use for most programmers, would need powerful libraries. Language designers would have to address the requirements of writers of libraries, who do need some of the complicated language constructs that many programmers may never need to use. A good example is Spirit - http://www.boost.org/doc/libs/1_37_0...ick_start.html
I still remember how my perspective changed after reading chapers 25 and 26 of this book:
Just as they have to adress the needs of compiler wtiters; the features can not be too complicated that it would cause genuine problems of compiler writers. For example, one reason (in addition to others that were presented) why a full compile-time interpreter can not be mandated by the language is that it would present a terribly expensive to solve problem for writers of cross-compilers. For example, they would have to emulate a target environment's floating point arithmetic.
Originally Posted by Bjarne Stroustr
Sorry for barging in but I would like to add more focus to the OP's question. The [] syntax is here to stay, I assume. However, the main complaints (in addition to the double subscript notation) are:
1) grouping multiple attributes, e.g. [[override, nothrow, noreturn]].
2) placing the attribute before the function's name:
[[override, nothrow, returnstwice]] pid_t fork();
3) empty attributes, as in: [] int func();
All these were invalid in the original proposal. They are all valid now, AFAIK, and if I'm wrong please let the readers and myself know.
I answered about attributes in message #17 and I don't really have anything to add to that. I'm not a great fan of attributes of any kind.
I'm not fond of attributes either because they seem like a solution to a non-existing problem in C++, and I bet that programmers will overuse them just because they're ornate and new.
Originally Posted by Bjarne Stroustr
So, would you advise programmers to avoid attributes?
I would recommend programmers to avoid all attributes whenever they can, but note that sometimes compiler and platform vendors can make that hard. The purpose of attributes is to say things that cannot be said in the language itself.
Originally Posted by Danny
I beg to differ. It's important to criticize problematic and controversial features right when they are proposed. Trust me, the criticism will percolate and reach the right people. That doesn't necessarily mean they will revise or withdraw their proposal (or that your critique is right) but if there's one good lesson I've learned in the past couple of years it's this one: don't wait until it's too late.
Originally Posted by Xarx
And no. You're not required to come up with an alternative. I've criticized several features before. The "alternatives" I've proposed were not to have that feature in the standard in the first place.
Don't hesitate to criticize when you believe that the author is not aware of a certain problem, or (I regret to say), when you feel that the authors of a certain proposal are enamored of their proposal (just to clarify: I'm not hinting at concepts here. rather, I'm hinting at proposals that are in the WD).
With respect to "over-complication" I think you need to draw a clear line between two issues:
1)truly complicated features that will be difficult to learn and use properly.
2) moot features that aren't necessarily complicated but aren't useful or needed either. Attributes are a clear example of this. I can live with the [] syntax somehow but I still don't understand why I need attributes in C++ in the first place. Especially when the C++0x proposal is far too different from the .Net attributes (and anyway, Microsoft's delegates have clearly stated they're refusing to implement the C++0x attributes). Lambdas are a limbo case: the syntax isn't delightful but it was much worse. I'm still not convinced that they are that useful, but perhaps time will prove I was wrong. Or it won't.
Last edited by Danny; 03-08-2010 at 11:34 AM.
Timely, considered, and reasonably polite criticism is always welcome. Too many people wait until it is too late to make changes and some are rude about it also. Please remember "the committee" are hardworking volunteers trying to serve a huge community.
Concerning the critique:
I didn't want to critisize only because my misunderstanding - that's why I asked first. Also I wasn't sure I'm in a right forum :-). And at third, my experience says that people don't like changing their opinions - unless forced to by good arguments. Otherwise I agreee with you.
> The "alternatives" I've proposed were not to have that
> feature in the standard in the first place.
That's also my opinion concerning several features we were discussing above, mainly attributes and lambdas. IMO they're not ready yet and they unnecessarily delay the finalization of the standard.
> moot features that aren't necessarily complicated but aren't
> useful or needed either. Attributes are a clear example of this.
It seems to me that we all (who are discussing in this thread) have a similar opinion on this. When you've written that "attributes...seem like a solution to a non-existing problem in C++", you've said in better words what I'd tried to express by the term "over-complication".
we consider C++ to be a modern language, don't we? So we should compare it to other modern languages like C#, Java or scripting languages, not to C.
IMO it is not an coincidence that the number of C++ programmers is lowering, while the number of programmers of the other named programming languages is growing (at least in my country). IMO the reason is mainly in that those languages are much easier to learn *and* use, and thus more suitable for "daily" programming. But this also results in that C++ programmers are much more expansive and hard to find than say C# programmers.
On the projects I've participated, most workers were juniors under 30, and very few knew C++. Juniors are cheap, and cheap programmers don't know such complicated languages like C++. But what the cheap programmers know determines what is considered a mainstream programming language.
To support high level / business programming, we need smart pointers so that "coders" don't have to meditate on every pointer whether they should or should not free it. We need anonymous functions and closures e.g. to support event-driven programming. We need simpler means to support concurrency and esp. deterministic concurrency. C++0x gives us some of these high-level features, but not many and often with strange syntax.
Until C++ contains features that make high level C++ programming similarly productive and easy to learn as programming in the other languages, C++ will be becoming a "special purpose" language. Currently C++ lacks those features, and C++0x does not much to improve it. I'm saying that even though I like C++ more than e.g. C#.
Last edited by Xarx; 03-08-2010 at 09:55 PM.
Reason: corrected typo
I must emphasize that there already exist working implementations of GC. From my point of view, their main drawback is their non-standard interface - if you target one GC, you cannot easily replace it with another, or reference counting. This is what I expect from the C++ standard - the GC interface standardization. C++0x offers the GC ABI which allows to build an object wrapper around it. But this alone is not sufficient and has at least two deficiencies:
What other models of sharing would you like to see, considering that shared_ptr was designed when C++ didn't officially support multithreading? Recall that you can use the small and efficient unique_ptr class in some cases. Allowing an underlying GC to replace the current shared_ptr model of resource management is quite problematic because GCs aren't deterministic and that means that shared_ptr wouldn't be able to own objects with destructors. This very issue is what makes GC so complex in C++.
(1) you have to create your own non-standard smart pointers and (2) some types of more sophisticated GCs cannot be used (though Bjarne said otherwise).
What a general GC needs to work in the C++ environment is visible in the Microsoft's interface to .NET (C++/CLI). Here e.g. you have to lock the smart pointer when deriving an ordinary pointer from it - shared_ptr lacks this, and thus cannot be used IMO to copying (or partially copying) GC.
Concerning the ownership: It all depends what you mean by that notion. I would consider an object not owned by anyone if it is available for GC - even when it is still not deleted. Moreover, we can separate the object destruction from the memory deallocation - the latter could be handled by the GC, the former as usual (though other models are possible).
>It is claimed that the ABI can be used with a copying collector.
I cannot imagine how that would work.
>copying collector requires twice as much memory as no GC
I don't think it's true. Anyway, much more interesting than pure copying collectors are generational partially copying collectors. I won't be talking about C++ where it (I think) cannot be done, but the Microsoft's .NET GC is said to be of this kind. And it performs well.
> For almost all uses, I prefer unique
> ownership as represented by unique_ptr.
You've mentioned an array of unique_ptr as an example in your articles. If this code would be in a library, it would prevent IMO the library users to put an objects from the array aside, because the object wouldn't survive the array. And the programmers wouldn't be able to do anything about it - due encapsulation.
>lambdas are not polymorphic
Do I understand it correctly that you cannot assign lambda to a function pointer of the same signature? If this is true, lambdas are certainly not ready for the standard yet!
A question: C++0x lambdas seem to emulate closures by copying the values of referred free variables. Closures are usually implemented by forking the execution stack or similar mechanisms based on garbage collection. Can be the C++0x implementation considered a true closure, or is it just a bare emulation? (I'm already aware of several limitations, but I'm not sure how much they are fundamental.)
> it is not a bad thing to have the compile-time features a bit
> restricted to minimize confusion in the very-hard-to-debug
> compile-time context
I agree with you, you probably didn't understand me. I was trying to say that it is good that there are limitations on constexp. And it is bad that no limitations are put on attributes.
With respect to lambdas and closures: the current intent is to have the compiler transform a lambda expressions into a local function class and instantiate it at the place of call, so the data from the enclosing scope referred into the lambda capture is either copied or becomes a reference variable inside the function object. In other words, lambdas rid the programmer of the tedium of writing a functor, they do not use magical tricks such as forking the execution stack.
Last edited by Danny; 03-10-2010 at 01:21 PM.
There is a vast literature on GC. Modern collectors can work quite well for a lot of uses, but they do tend to use a lot of memory. The complexities are such that there isn't much I can say in a short message, but "I cannot imagine" and "I do not think" should be validated against the literature and/or backed with measurements.
Originally Posted by Xarx
-- Android Development Center
-- Cloud Development Project Center
-- HTML5 Development Center
-- Windows Mobile Development Center