- "Death to C, ++" - 17 Updates
- Difference between type(type) and type(*)(type) - 5 Updates
- optional va_args argument - 3 Updates
Siri Cruise <chine.bleu@yahoo.com>: Jul 19 05:20PM -0700 In article <Q6KdnWzp9tvHfvLEnZ2dnUU78K3NnZ2d@giganews.com>, > language or the programmer is not able to manage the object lifetimes > properly. But thanks to RAII C++ is fully capable to manage the object > lifetimes properly. Try directed graphs that can include cycles. You can't free a node until all incoming edges are cut. So you have to keep a count of incoming edges (reference count), but reference counts can't reclaim an isolated cycle. This is a well known limitation of reference count. Apple's ObjC does it by distinguish forward edges and back edges, with only forward edges contributing to reference count. However no general way distinguishes which should be which, so you have to encode domain information into a generic graph package. Another way is to reimplement mark and sweep, poorly, by linking all the active and inactive nodes in a list and then sweeping the list with domain knowledge to decide which nodes can be deleted. Any data structure which can be a cyclic directed graph cannot be handled with a single generic graph package which isolates all graph construction from domain specific nodes and edges. -- :-<> Siri Seal of Disavowal #000-001. Disavowed. Denied. Deleted. @ 'I desire mercy, not sacrifice.' /|\ Free the Amos Yee one. This post / \ Yeah, too bad about your so-called life. Ha-ha. insults Islam. Mohammed |
legalize+jeeves@mail.xmission.com (Richard): Jul 20 03:29AM [Please do not mail me a copy of your followup] Manfred <noname@invalid.add> spake the secret code >One thing that C and C++ share in common is that they are both languages >that are not meant to be handled superficially or without enough >knowledge. One reason I think this attitude is prevalent is because people learn C++ by learning C first. Either it is explicitly taught to them that way in a C++ course, or they keep seeing crappy C-style C++ code and think that is C++. Seriously, I haven't had resource leak errors since I learned the standard library for containers and used smart pointers for managing heap storage. It just doesn't happen anymore. Anyone who teaches C++ by starting you out with new/delete, or even worse malloc/free, is someone who isn't teaching you C++. Hell, they aren't even teaching you C++98, never mind C++17. I've written a lot of code in C. I'm more productive without any loss of performance (measure twice, optimize once) when I write code in C++. This is due to the abstraction facilities available to me in C++ -- which are many -- compared to the paucity of such facilities in C -- structs and functions. It is possible to write a large OO-oriented application in C. The best example is the X11 Window Server sample implementation from MIT. Really. Go read it, it's awesome. But it's clear that you could do the same thing with simpler coding and less error-prone mechanisms in C++ than they did in C. They used C because it was the least common denominator of the day (mid 80s). They used OO-oriented programming because it makes sense for an extensible GUI server. -- "The Direct3D Graphics Pipeline" free book <http://tinyurl.com/d3d-pipeline> The Terminals Wiki <http://terminals-wiki.org> The Computer Graphics Museum <http://computergraphicsmuseum.org> Legalize Adulthood! (my blog) <http://legalizeadulthood.wordpress.com> |
legalize+jeeves@mail.xmission.com (Richard): Jul 20 03:36AM [Please do not mail me a copy of your followup] jacob@jacob.remcomp.fr spake the secret code >> code (or C++ written in C code style). >Thanks for repeating the mantra of all incompetent C++ programmers: >C is bad. C itself is fine. C requires a significant amount of personally imposed disciplnie to keep it maintainable. I've written tons of C code. C has weak abstraction mechanisms, therefore you have to impose self discipline to create those abstractions yourself and implement the mechanics yourself. As I said earlier in this thread, go read the X Window System server sample implementation. It's great. However, it is easier to do the same thing in C++. That is, after all, what C++ was designed to do: retain the direct map to the hardware that C provides while adding the higher level abstraction facilities that C is missing. >And that is not backed up with any real data. Just stories as they like >to tell, to mask their lies. Well it's nice to have you put words in my mouth. >There is not a single thread of evidence that C code is "unmaintainable" >any more than C++ code is. C is readable, C++ is NOT. This is a straw man. I never said this. I simply said that when other people show me their examples of horrible code, it is flagrant examples of the kinds of poorly written code that comes from people who have C programming habits. They didn't have discipline imposed on them by a strong type system and they also didn't impose any discipline on themselves and they wrote crap. This, in turn, is used by the C# or Java afficionado as "proof" that C/C++ is a "bad language" because it allowed such undisciplined programming to compile. I already addressed earlier that you can write shit in any language, but my point was that when fans of other languages show me examples of why "C++ is bad", they are showing me code that isn't even typical of C++ code written 15 years ago, much less typical C++ code that is written today. They're laying the blame on the language and not the author. >You just cannot go into all those nested templates, classes, whatever. >You MUST use the debugger to see where that code is going. >This is a fact. No, it's an opinion. But hey, you must be one of those people that can't leave the Christian religion trolls alone without feeding them because you've already ended up in my KILL file for some reason, so I am probably not going to spend any more time replying to your messages on this thread. -- "The Direct3D Graphics Pipeline" free book <http://tinyurl.com/d3d-pipeline> The Terminals Wiki <http://terminals-wiki.org> The Computer Graphics Museum <http://computergraphicsmuseum.org> Legalize Adulthood! (my blog) <http://legalizeadulthood.wordpress.com> |
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Jul 20 05:46AM +0200 * On 20.07.2017 02:20, Siri Cruise wrote: >> properly. But thanks to RAII C++ is fully capable to manage the object >> lifetimes properly. > Try directed graphs that can include cycles. In the case of a graph where the number of added nodes (from creation of the graph) is never unreasonably large, one can simply let the graph's nodes be owned by a graph object, and defer destruction of individual nodes until the graph as a whole is destroyed. But what if nodes in a graph may refer to nodes in other graphs, or the number of added nodes, over time, can be Really Great? Well then one needs garbage collection, unless there is some special property that can be leveraged. But a garbage collector that's special purposed for graph nodes, can probably be far more efficient and in tune with the application requirements for responsiveness etc., than a completely general garbage collector. So, since this is the only problem that over the years has popped up showing a definite need for garbage collection, I think we need a sort of standardized set of requirements on graph nodes, that support a standard graph node collector. ;-) Cheers!, - Alf |
Juha Nieminen <nospam@thanks.invalid>: Jul 20 04:29AM > C++ sucks because, besides the rampaging featurism, it tries to do automatic storage > collection without garbage collection. It means things like closures cannot be > implemented without considerable work by the programmer. I have always loved the oxymoronic argument of "C++ is too large! And it doesn't have feature X!" So which is it, it has too many features, or it doesn't have enough features? It needs less programming paradigms, or more of them? Make up your mind. If the criticism is this contradictory, then it doesn't sound very valid. |
Juha Nieminen <nospam@thanks.invalid>: Jul 20 04:31AM > incoming edges are cut. So you have to keep a count of incoming edges (reference > count), but reference counts can't reclaim an isolated cycle. This is a well > known limitation of reference count. Yeah, that makes things like automatically managed double-linked lists impossible. Oh, wait... |
Siri Cruise <chine.bleu@yahoo.com>: Jul 19 10:05PM -0700 In article <okpbm4$1vf6$2@adenine.netfront.net>, > Yeah, that makes things like automatically managed double-linked lists > impossible. > Oh, wait... That's a form of a cyclic directed graph, with distinct forward and back edges. -- :-<> Siri Seal of Disavowal #000-001. Disavowed. Denied. Deleted. @ 'I desire mercy, not sacrifice.' /|\ Free the Amos Yee one. This post / \ Yeah, too bad about your so-called life. Ha-ha. insults Islam. Mohammed |
Gareth Owen <gwowen@gmail.com>: Jul 20 06:07AM +0100 >> adds several layers of language specific problems. > What I don't get is why you can't recognise that C++ can simplify > spaghetti C code. Because - as he has proven over and over again - he has literally no interest in anything that challenges how he has already made his mind up. C++ is bad and unreadable, C is smooth and elegant |
Paavo Helde <myfirstname@osa.pri.ee>: Jul 20 09:47AM +0300 On 20.07.2017 8:05, Siri Cruise wrote: >> impossible. >> Oh, wait... > That's a form of a cyclic directed graph, with distinct forward and back edges. Yes, but this distinction is not required or utilized by std::list implementations, they handle both edges very much symmetrically. You also appear to claim that C++ graph classes like boost::adjacency_list are impossible. If you want to have cyclic graphs, then use a graph class instead of inventing your own mess. And if you have an heterogeneous net of objects which can contain cycles then you should better make up your mind in advance and decide which links are to be handled by std::weak_ptr. If you do not, then you will get more problems than just memory leaks, starting from infinite loops and stack overflows. |
Siri Cruise <chine.bleu@yahoo.com>: Jul 20 12:26AM -0700 In article <_7qdnZo87OSLz-3EnZ2dnUU78VPNnZ2d@giganews.com>, > > edges. > Yes, but this distinction is not required or utilized by std::list > implementations, they handle both edges very much symmetrically. In a SLIP list node, links in one direction are forward edges, and links in the other are back edges. Discounting back edges, they are acyclic and not branching, so you can apply that knowledge to their management. That's why you can make a SLIP garbage collector which is not mark-sweep. And trees are acyclic and do not rejoin branches, so you can apply that knowledge to make a tree garbage collector. Gosh! What a surprise! For data structures that cannot be cyclic DGs, you can write a specialised collector for each one. > You also appear to claim that C++ graph classes like > boost::adjacency_list are impossible. If they support cyclic DGs, you can't collect all garbage without some form of mark-sweep or encoding domain specific knowledge about when a cycle becomes garbage. > inventing your own mess. And if you have an heterogeneous net of objects > which can contain cycles then you should better make up your mind in > advance and decide which links are to be handled by std::weak_ptr. If Quoth: Apple's ObjC does it by distinguish forward edges and back edges, with only forward edges contributing to reference count. However no general way distinguishes which should be which, so you have to encode domain information into a generic graph package. -- :-<> Siri Seal of Disavowal #000-001. Disavowed. Denied. Deleted. @ 'I desire mercy, not sacrifice.' /|\ Free the Amos Yee one. This post / \ Yeah, too bad about your so-called life. Ha-ha. insults Islam. Mohammed |
"Chris M. Thomasson" <invalid@invalid.invalid>: Jul 20 12:37AM -0700 On 7/20/2017 12:26 AM, Siri Cruise wrote: > If they support cyclic DGs, you can't collect all garbage without some form of > mark-sweep or encoding domain specific knowledge about when a cycle becomes > garbage. Fwiw, proxy garbage collection is fairly nice, and can be implemented using pure C++: https://groups.google.com/d/topic/lock-free/X3fuuXknQF0/discussion (read all) |
Richard Heathfield <rjh@cpax.org.uk>: Jul 20 11:09AM +0100 On 20/07/17 04:36, Richard wrote: >> C is bad. > C itself is fine. C requires a significant amount of personally > imposed disciplnie to keep it maintainable. Agreed. C and C++ are, in this respect, like any other language - it is possible to write readable code, and it is possible to write unreadable code, in either C or C++. >> There is not a single thread of evidence that C code is "unmaintainable" >> any more than C++ code is. C is readable, C++ is NOT. > This is a straw man. I never said this. Fine. But it's partly true anyway. A more accurate rendition would be: Some C is readable. Some is not. Some C++ is readable. Some is not. <snip> >> This is a fact. > No, it's an opinion. But hey, you must be one of those people that > can't leave the Christian religion trolls alone without feeding them He is. > because you've already ended up in my KILL file for some reason, No, he hasn't. If he had, you would not have replied to him, because you would not even have seen his message. That's the joy of kill files. I suggest you read up on what they are, what they're for, and why it's a good idea to use them. > so I > am probably not going to spend any more time replying to your messages > on this thread. If you had a kill file, you could s/ probably// -- Richard Heathfield Email: rjh at cpax dot org dot uk "Usenet is a strange place" - dmr 29 July 1999 Sig line 4 vacant - apply within |
Bo Persson <bop@gmb.dk>: Jul 20 01:03PM +0200 On 2017-07-19 22:51, jacobnavia wrote: > c = foo(pData,42); > Is this a macro or a function call? Here C++ shares the lack of > distinction between macros and function calls of C. In C++ this would be c = pData->foo(42); and pretty obvious that it is a member function. So obvious that you might even remove the p prefix from pData. Bo Persson |
James Kuyper <jameskuyper@verizon.net>: Jul 20 08:08AM -0400 On 07/20/2017 12:29 AM, Juha Nieminen wrote: > I have always loved the oxymoronic argument of "C++ is too large! And it doesn't > have feature X!" > So which is it, it has too many features, or it doesn't have enough features? Neither - when people say that, what they actually mean is that it has a bunch of features they don't want, as well as lacking certain features they do want. It's the same problem as the government budget - it would be trivial to avoid running a deficit if the government did everything I want it to do, and nothing that I didn't want it to do - but then there's all of those other voters who have different opinions about what the government should and should not do, and the best you can hope for is a compromise that leaves everyone equally unhappy (and expenditures exceeding tax revenues). With C++, the same mechanism leaves you with a language with two many features for everyone to become fully familiar with all of them in a reasonable amount of time. Everyone seems to program in their own chosen subset of C++, and to be confused by code which uses a different subset. |
"Mr. Man-wai Chang" <toylet.toylet@gmail.com>: Jul 20 09:08PM +0800 On 19/7/2017 1:34 AM, Lynn McGuire wrote: > But, if one cannot walk the tightrope then one should find something > else to do in life. After all, working on the high wire is not for > everyone. Both C and C++ have proven their values. No reasonable doubts. -- @~@ Remain silent! Drink, Blink, Stretch! Live long and prosper!! / v \ Simplicity is Beauty! /( _ )\ May the Force and farces be with you! ^ ^ (x86_64 Ubuntu 9.10) Linux 2.6.39.3 不借貸! 不詐騙! 不援交! 不打交! 不打劫! 不自殺! 請考慮綜援 (CSSA): http://www.swd.gov.hk/tc/index/site_pubsvc/page_socsecu/sub_addressesa |
legalize+jeeves@mail.xmission.com (Richard): Jul 20 03:30PM [Please do not mail me a copy of your followup] Richard Heathfield <rjh@cpax.org.uk> spake the secret code >Fine. But it's partly true anyway. A more accurate rendition would be: >Some C is readable. Some is not. >Some C++ is readable. Some is not. A tautology is a thing that is tautological. You can make similar statements for any language. Saying this isn't adding anything to the conversation, however. >> because you've already ended up in my KILL file for some reason, >No, he hasn't. If he had, you would not have replied to him, because you >would not even have seen his message. I saw his reply quoted in someone else's message on the thread and went back to respond to some of the points. So yes, he is in my KILL file, but that doesn't prevent me from going back and reading a KILLed message and replying to it if I so choose. >If you had a kill file, you could s/ probably// My KILL file serves me, not the other way around :). -- "The Direct3D Graphics Pipeline" free book <http://tinyurl.com/d3d-pipeline> The Terminals Wiki <http://terminals-wiki.org> The Computer Graphics Museum <http://computergraphicsmuseum.org> Legalize Adulthood! (my blog) <http://legalizeadulthood.wordpress.com> |
Richard Heathfield <rjh@cpax.org.uk>: Jul 20 04:53PM +0100 On 20/07/17 16:30, Richard wrote: >> Some C++ is readable. Some is not. > A tautology is a thing that is tautological. > You can make similar statements for any language. Quite so. In other words, Jacob's claim was without merit, despite being partly true. > Saying this isn't adding anything to the conversation, however. The conversation, too, is without merit. Language wars are pointless. Everybody has likes and dislikes, and what attracts some people to a language will repel others from it. That's /why/ we have different languages. > went back to respond to some of the points. So yes, he is in my KILL > file, but that doesn't prevent me from going back and reading a KILLed > message and replying to it if I so choose. Fair enough. It's quite common for people to claim that they have added a subscriber to their killfile when in fact they don't even /have/ a killfile. It is now clear that you don't fall into that category, so I withdraw the insinuation and apologise for it. De gustibus non est disputandum and all that, but despite many exchanges with Jacob that have bordered on the acrimonious (and indeed crept over that border on occasion) I have never killfiled him, because I have a considerable amount of respect for him (although this may come as a surprise to him!). I think many of his communication difficulties in comp.lang.c come down to the fact that his English is very, very good, and so we tend to forget that it is his /second/ language, and instead wrongly assume that he has the usual native mastery of idiom and phrasing. This is almost certainly at the root of quite a few breakdowns in communication. Given that he has maintained lccwin32 more or less single-handedly for at least 20 years and it *still works*, I am inclined to cut him a little slack. <snip> -- Richard Heathfield Email: rjh at cpax dot org dot uk "Usenet is a strange place" - dmr 29 July 1999 Sig line 4 vacant - apply within |
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Jul 20 05:33AM +0200 On 19.07.2017 20:46, Manfred wrote: > [snip] > It looks that the type(type) syntax, which was introduced in C++11 as > /call signature/ (20.14.1) to identify a function type, Oh, the `type(type)` syntax is as old as C++, mostly. When you declare formal argument of type `type(type)`, then it decays to pointer to function, just as an array type decays to pointer to item. And that's been so wrt. the standard, since C++98. Cheers!, - Alf |
Ben Bacarisse <ben.usenet@bsb.me.uk>: Jul 20 10:49AM +0100 >> [snip] >> It looks that the type(type) syntax, which was introduced in C++11 as /call signature/ (20.14.1) to identify a function type, > Oh, the `type(type)` syntax is as old as C++, mostly. The syntax for a function type is in pre-ANSI C (often called K&R C) but since there are no prototypes in K&R C the only valid form is type(). > When you declare formal argument of type `type(type)`, then it decays > to pointer to function, just as an array type decays to pointer to > item. The use in a parameter list, and the implicit type adjustment, are also in ANSI C (1989) but it's not clear if C++ got it from ANSI C or ANSI C got it from proto-C++. After all, the whole idea of function prototypes came from the experiments being done with C++ at Bell Labs. K&R is silent on the question of whether a parameter can be declared with a function type and what, if any, the semantic of that are. <snip> -- Ben. |
"Öö Tiib" <ootiib@hot.ee>: Jul 20 05:03AM -0700 On Thursday, 20 July 2017 00:00:24 UTC+3, Manfred wrote: > > Function is not object and so can not be copied. The std::map is very > > desired to be assignable so how it makes sense? > In the same way as std::function<> is. Hmm. I was incorrect above. :( Comparator object of map is not copied when map is assigned, it is set at construction and done. The allocator may be copied (if its traits show that there is a point to). Sorry. The real reason why standard containers and algorithms are made differently than std::function is likely to make it easy for compiler to optimize by inlining the calls of function objects (like predicates or hashers passed) in containers and algorithms. The std::function however is doing type erasure. That means in it there are type-erased pointers. Compilers have difficulties to inline calls thru such pointers. That is usually insignificant cost (loss of 10 nanoseconds per call on my desktop PC). However such cost can matter on case of containers and algorithms that when working with large data can do lot of such calls and take noticeable part of run-time. For example that difference is what makes std::sort to be faster (sometimes by quarter sometimes twice) than equivalent qsort. ... > > is a function. Therefore function is not function object since it is not > > an object. > You are right, according to how the language works, thanks! Always happy to discuss. :) Note that some of how the language works is legacy from past. The array/pointer and function/pointer relations are so in C. The C++ (and the Objective-C even more) are so very careful to keep the common subset with C as large as possible. That allows people to who want to be picky and to use its features very conservatively to do so. > However, if you think in terms of pure metaprogramming (which Bjarne > likes a lot), handling functions as objects is exactly why features like > std::function<> have been introduced. The std::function is not like std::array (whose main purpose is to fix the inconveniences of raw array) it is way more clever beast. Type erasure of std::function is not about metaprogramming but about making coupling in interface as loose as possible. > works. This is what I meant above for "non uniform" deployment. > Beware, it may very well be that this would be too much obfuscation (see > below), my remark here is only about theoretical semantics. Yes, std::function is great since it allows us to be minimally intrusive in interface dynamics. You did have it in your example: std::map<const char*, int, std::function<bool(const char*, const char*)>> m2; That shows that we can use it (when needed) in interface of standard containers and algorithms. But we do not usually want a predicate or hash of standard container to be dynamically integrated. Instead we want optimizations like I explained before. Little demo: #include <iostream> #include <functional> #include <map> bool myCompare(int a, int b) {return b < a;} int main(int argc, char* argv[]) { using FlexComparator = std::function<bool(int, int)>; // that FlexComparator is very dynamically flexible: FlexComparator comp; if (argc%2 == 1) comp = std::less<int>(); else comp = myCompare; // Note that ?: does not work in style of: // FlexComparator c = argc%2 == 1 ? std::less<int>() : myCompare; // it will not compile since ?: is not so dynamic as we need // Now we can do flexible map type with FlexComparator: using FlexMap = std::map<int, const char*, FlexComparator>; // Note that following line will throw if we forget comp FlexMap nums({{1, "One"}, {4, "Four"}, {2, "Two"}}, comp); for (auto n : nums) { std::cout << n.first << ": " << n.second << std::endl; } } Nice. But compiler can't optimize that FlexMap since compiler can not predict what value argc will have. Therefore we must explicitly put std::function there if we want such flexibility. |
Manfred <noname@invalid.add>: Jul 20 04:46PM +0200 On 7/20/2017 5:33 AM, Alf P. Steinbach wrote: > When you declare formal argument of type `type(type)`, then it decays to > pointer to function, just as an array type decays to pointer to item. > And that's been so wrt. the standard, since C++98. Great! Never used it before C++11 (always used good old function pointers) I learnt a bit of history today, thanks! |
"Öö Tiib" <ootiib@hot.ee>: Jul 20 08:00AM -0700 On Thursday, 20 July 2017 15:03:56 UTC+3, Öö Tiib wrote: > Hmm. I was incorrect above. :( Comparator object of map is not copied > when map is assigned, it is set at construction and done. The allocator > may be copied (if its traits show that there is a point to). Sorry. Oh scratch it. Seems that I was still correct on first time and it is copied, just can't find it in standard. |
Gareth Owen <gwowen@gmail.com>: Jul 20 06:06AM +0100 >> which is an opaque implementation defined type. > It may be not legal now, but it compiled without any problem until > 2016 for at least a dozen of years. That's how opaque types work. If you guess their type correctly for a particular compiler, the compiler won't complain, but its not portable (as you've discovered). As you well know, in C there's a big difference between something that compiles & works in C or C++, and something that is actually defined as legal. |
Bo Persson <bop@gmb.dk>: Jul 20 12:57PM +0200 On 2017-07-19 20:03, jacobnavia wrote: > 'va_list {aka __va_list}' > How could I fix that? > There are MANY calls to those functions all over the place. One option to default arguments is to add an overload with fewer paramters, like: void SetErrorN(ErrorCode ec, int mc); which just sets the error code with no additional message. Bo Persson |
Manfred <noname@invalid.add>: Jul 20 04:52PM +0200 On 7/19/2017 10:44 PM, Ian Collins wrote: >> explicitely is not clear. I suppose the default assignment is discarded >> and the variable has the actually passed in value. > The args parameter *is* passed by value! This is not always the case. x86_64 defines it as an array of length 1, which is passed by reference (I learned it the hard way) |
You received this digest because you're subscribed to updates for this group. You can change your settings on the group membership page. To unsubscribe from this group and stop receiving emails from it send an email to comp.lang.c+++unsubscribe@googlegroups.com. |
No comments:
Post a Comment