- ""Rust is the future of systems programming, C is the new Assembly": Intel principal engineer, Josh Triplett" - 13 Updates
- Weird use of maps. - 9 Updates
- What is easiest to use static C++ code analyser? - 1 Update
- Should I use Release-Acquire ordering or Sequentially-consistent ordering to implement spinlock with atomic? - 1 Update
- Why does this work on Xcode ??? - 1 Update
| Melzzzzz <Melzzzzz@zzzzz.com>: Aug 29 02:36AM > he also spoke about the history of systems programming, how C became the > "default" systems programming language, what features of Rust gives it > an edge over C, and much more." Rust is nowhere near C. Actually, nowhere near C++. It is nice language, but not for low level programming. During years they ditched GC and most of the things that cripples determinism and performance, it is ok, but without pointer arithmetic and null pointers it is high level language. Having to convert pointer to int and back in order to perform arithmetic is worse that doing it in assembler. But what Rust got it right is error handling, much better than excpetions. But not having inheritance and forbidding two mutable references to distinct array elements is stupid. Also no tail recursion optimisation and no way to disable array checks. -- press any key to continue or any other to quit... U ničemu ja ne uživam kao u svom statusu INVALIDA -- Zli Zec Na divljem zapadu i nije bilo tako puno nasilja, upravo zato jer su svi bili naoruzani. -- Mladen Gogala |
| David Brown <david.brown@hesbynett.no>: Aug 29 11:02AM +0200 On 29/08/2019 04:36, Melzzzzz wrote: > without pointer arithmetic and null pointers it is high level language. > Having to convert pointer to int and back in order to perform arithmetic > is worse that doing it in assembler. That sounds terrible. (I am not very familiar with Rust.) > But what Rust got it right is error handling, much better than > excpetions. But not having inheritance and forbidding two mutable > references to distinct array elements is stupid. I have worked with a C-like language which had that many of that kind of restriction (XC for the XMOS microcontrollers, if anyone is curious). For a lot of code, it can be helpful - it allowed the compiler to find lots of situations that could be problematic, especially in heavily threaded and parallel code. But you invariably had situations where the restrictions were too much - you needed shared access, or whatever, in cases where you know they are safe. This typically lead to inline assembly code to get round the safety limitations imposed by the language and compiler - that was /not/ a good situation! > Also no tail recursion optimisation and no way to disable array checks. Surely tail recursion optimisation is just a matter of the compiler? C and C++ don't have any mention of such optimisations in their standards, but a compiler can do it as long as the code works under the "as if" rule. Does the same not apply to Rust? As for array checks, again I would think a compiler could elide a fair number of them, reducing the cost of having them on all the time. One thing that I gather Rust does well, that C++ has trouble with, is that when you do the Rust equivalent of std::move'ing something, any attempt to use the moved-from object is flagged by the compiler. I think that would be good to spot in C++. |
| BGB <cr88192@gmail.com>: Aug 29 05:14AM -0500 On 8/28/2019 4:11 PM, Lynn McGuire wrote: > he also spoke about the history of systems programming, how C became the > "default" systems programming language, what features of Rust gives it > an edge over C, and much more." How about, instead: We take C; We add some features to support things like bounds-checked arrays and similar; We mostly call it done. Many past variants of bounds-checked arrays did funky things with the syntax, which is a problem if one wants to be able to make it work in a compiler without support for this feature (eg: via non-convoluted use of defines). My thought is, say: _BoundsCheck int *arr; Which behaves sorta like "int[] arr;" in Java or similar. Then it is given a shorthand in a header (eg: bounded), which becomes no-op if the compiler doesn't support it. Otherwise, it behaves mostly like a normal pointer, apart from potential runtime bounds checking, and a different internal representation. May decay into a normal pointer, potentially with a warning. While at it, something like a standardized header for accessing misaligned and explicit endianess values would be nice. eg: uint32_t getuint32le(void *ptr); void setint32le(void *ptr, int32_t val); ... Where: le: little endian, be: big endian, no suffix: native endian. And, these functions work regardless of alignment. This being semi-common boilerplate one either needs to copy around or reimplement fairly often (and for which the optimal way to do these varies between compilers; and with some dependence on target architecture). |
| Ian Collins <ian-news@hotmail.com>: Aug 29 10:21PM +1200 On 29/08/2019 21:02, David Brown wrote: > that when you do the Rust equivalent of std::move'ing something, any > attempt to use the moved-from object is flagged by the compiler. I > think that would be good to spot in C++. clang-tidy does a pretty good job with "bugprone-use-after-move" <https://clang.llvm.org/extra/clang-tidy/checks/bugprone-use-after-move.html> -- Ian. |
| David Brown <david.brown@hesbynett.no>: Aug 29 01:24PM +0200 On 29/08/2019 12:21, Ian Collins wrote: >> think that would be good to spot in C++. > clang-tidy does a pretty good job with "bugprone-use-after-move" > <https://clang.llvm.org/extra/clang-tidy/checks/bugprone-use-after-move.html> Yes, I saw that after googling a bit. I would have thought, however, that pretty much any use (other than assignment of some sort) of a named object after it is moved, is likely to be a bug. And it is therefore something that could be warning about by default. #include <memory> extern int a, b, c; void foo(void) { auto p = std::make_unique<int>(3); a = *p; auto q = std::move(p); b = *q; c = *p; } Both clang and gcc are smart enough to move the value 3 directly into "a" and "b", and if the last line is omitted, they can remove the call to "new" (at least in their trunk versions). Both are smart enough to know that "c = *p;" is undefined behaviour here, and generate "ud2" instructions on x86. Yet neither compiler warns about this clearly wrong behaviour despite -Wall -Wextra. |
| Ian Collins <ian-news@hotmail.com>: Aug 29 11:35PM +1200 On 29/08/2019 23:24, David Brown wrote: > instructions on x86. > Yet neither compiler warns about this clearly wrong behaviour despite > -Wall -Wextra. Use a bigger hammer! $ clang-tidy x.cc 1 warning generated. /tmp/x.cc:11:9: warning: Dereference of null smart pointer 'p' of type 'std::unique_ptr' [clang-analyzer-cplusplus.Move] c = *p; ^ /tmp/x.cc:9:14: note: Smart pointer 'p' of type 'std::unique_ptr' is reset to null when moved from auto q = std::move(p); ^ /tmp/x.cc:11:9: note: Dereference of null smart pointer 'p' of type 'std::unique_ptr' c = *p; -- Ian. |
| Bonita Montero <Bonita.Montero@gmail.com>: Aug 29 02:53PM +0200 Rust is nice, but Rust has no exceptions. I wouldn't like to evaluate this combined error- and return-values after each function-call that might fail. |
| Bonita Montero <Bonita.Montero@gmail.com>: Aug 29 02:54PM +0200 > Rust is nowhere near C. Actually, nowhere near C++. It is nice language, > but not for low level programming. During years they ditched GC and most > of the things that cripples determinism and performance, ... Rust has no GC, but works with counted references. |
| "Öö Tiib" <ootiib@hot.ee>: Aug 29 06:08AM -0700 On Thursday, 29 August 2019 13:14:29 UTC+3, BGB wrote: > We add some features to support things like bounds-checked arrays and > similar; > We mostly call it done. Rust supports lot of interesting safety features (like RAII, smart pointers, ownership, generics, move semantics, thread safety). Adding some safe features at side does not help as history with C++ shows. Result is bigger language with all the unsafe stuff still there and valid. OTOH if to cripple the unsafe features a bit then result is some kind of fourth language that is neither C, C++ nor Rust. |
| gazelle@shell.xmission.com (Kenny McCormack): Aug 29 01:14PM In article <qk8hrh$ua3$1@news.albasani.net>, >Rust is nice, but Rust has no exceptions. I wouldn't like to evaluate >this combined error- and return-values after each function-call that >might fail. Why is this posted to CLC? Surely, the comparison is more valid to C++, given that C++ has things like exceptions and so on. It should have only been posted to CLC++. (Or, is there a parallel thread going on in CLC++ - that I am not (yet) aware of?) P.S. Of course there will be a blogs and stuff like this one (the one referred to in the OP) telling us that Rust is the next big thing and obviously the thing that is going to be just so absolutely neato keeno that you'll be unable to imagine how we ever got along with it. This is true for any new programming language. Look at it this way: If a new programming language came out and there was no blog post (or whatever) telling us with absolute authority that this is the absolute greatest thing since, well, ever - that language will have zero, zip, nada chance of ever being used by anyone. -- Pensacola - the thinking man's drink. |
| Bonita Montero <Bonita.Montero@gmail.com>: Aug 29 03:38PM +0200 >> this combined error- and return-values after each function-call that >> might fail. > Why is this posted to CLC? ... Why do you post another Follow-Up there if you consider this as inadequate. |
| David Brown <david.brown@hesbynett.no>: Aug 29 08:00PM +0200 On 29/08/2019 13:35, Ian Collins wrote: >> Yet neither compiler warns about this clearly wrong behaviour despite >> -Wall -Wextra. > Use a bigger hammer! I might well do that. But it won't stop me wanting the feature in the tools I already use. |
| Keith Thompson <kst-u@mib.org>: Aug 29 01:29PM -0700 > On 29/08/2019 04:36, Melzzzzz wrote: [...] >> Having to convert pointer to int and back in order to perform arithmetic >> is worse that doing it in assembler. > That sounds terrible. (I am not very familiar with Rust.) What's terrible about it? Rust doesn't particularly need pointer arithmetic; unlike C, it's array indexing isn't defined in terms of pointers. [...] -- Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst> Will write code for food. void Void(void) { Void(); } /* The recursive call of the void */ |
| James Kuyper <jameskuyper@alumni.caltech.edu>: Aug 28 08:46PM -0400 On 8/28/19 10:22 AM, Jens Kallup wrote: > Hello, > QMap, and other template class "extend" the > corespond stdC++ std::map<k,v> class. Yes, I know that much about Qt. My point was that, as far as I can tell, the differences between the Qt classes and the standard classes are not relevant to the issues I was raising. If I'm wrong about that, please let me know. |
| James Kuyper <jameskuyper@alumni.caltech.edu>: Aug 28 08:58PM -0400 On 8/28/19 12:00 PM, Öö Tiib wrote: >> for transmission. Each part is transmitted along with a message ID, a >> part number, and the total number of parts. > How can receiver realize that all parts have been received? All parts have been received as soon as the number of different parts that have been collected for a given message ID matches the part count. > Is the message part count known compile time No, it varies with the length of the message provided by the user. > ... and part numbers > sequential and zero-based? The part numbers are sequential in the order that the parts should occur in. They are sent out sequentially, but in general, they don't arrive sequentially. They are 1-based, not 0-based. ... > did change into simpler and so it was cut out from something > way more overcomplicated. The file change history from repo > (and commit comments) may illuminate it a bit (if such exist). The entire block of code containing all of the features I described was added in 2015, and hasn't been changed since. Prior to that, multi-part messages weren't supported. The commit message didn't provide any explanation. I was wrong about the person responsible being unavailable - but I'm having trouble figuring out how to word an inquiry that doesn't make it sound like I think he wrote something stupid (since, in fact, that is what I'm thinking). > Results of developers with different skill levels differ by several > orders of magnitude, but no one notices when that inefficiency > is in some non-critical part of program. Agreed - the messages are provided by users, and therefore don't arrive frequently enough for the inefficiency of this approach to be a significant problem. The inefficiency bothers me, but my boss wouldn't have let me work on something this low in priority if I weren't currently stuck between a project I've finished and a project I'm not allowed to start work on (we're waiting for approval from the client). |
| James Kuyper <jameskuyper@alumni.caltech.edu>: Aug 28 09:05PM -0400 On 8/28/19 2:19 PM, Mike Terry wrote: > On 28/08/2019 14:30, James Kuyper wrote: ... >> the corresponding keys to reconstruct the original message. > That sounds so strange, that I wonder if there's a simple explanation: > the original coder just confused the ordering of the two map parameters? No, that explanation doesn't work. The code includes a comment indicating that he would have preferred to use QMap<int, QString>, but failed to clearly explain why he felt that he couldn't use it. > Perhaps the intention was to have a map by part number. If multiple > part numbers were encountered they would be deemed retransmissions and > it would be OK to just keep the latest one. ... I was rather confused by the fact that every part arrives at least three times - I suspect that's a bug, but I haven't tracked it down yet. ... > issues coming up would just be worked around. (Like, "hey, seems I need > to sort by values to get things in the right order?". Yes, seems a bit > crazy, but maybe the coder was new. That's what I suspect. ... > this. (Put another way, maybe the part map in message map either was, > or seemed (to the coder) to effectively be a const entry that could only > be updated through replacement, not modification...) Again, that's pretty much the confusion that I suspect happened. |
| James Kuyper <jameskuyper@alumni.caltech.edu>: Aug 28 09:08PM -0400 On 8/28/19 2:22 PM, Stefan Große Pawig wrote: > type, including possible conversions. Among these is toMap(), which > returns a QMap<QString, QVariant>. > Is that map of yours stored in another QVariant? No. The original message map was declared as QMap<QString, QVariant>, and the QVariant values were filled in with part maps of the type QMap<QString, int>. I successfully changed the message map to QMap<QString, QMap<int, QString> > without breaking anything, and that's because it doesn't interact with any other code that expected QVariants. |
| James Kuyper <jameskuyper@alumni.caltech.edu>: Aug 28 09:11PM -0400 On 8/28/19 3:33 PM, Jorgen Grahn wrote: > On Wed, 2019-08-28, James Kuyper wrote: ... > That's such an obvious flaw that I'd not trust the rest of that > programmers choices to make sense. It's simply not a sane way to do > the trivial task of message reassembly. I agree. |
| James Kuyper <jameskuyper@alumni.caltech.edu>: Aug 28 09:16PM -0400 On 8/28/19 9:08 PM, James Kuyper wrote: > No. The original message map was declared as QMap<QString, QVariant>, > and the QVariant values were filled in with part maps of the type > QMap<QString, int>. I successfully changed the message map to Correction: QMap<QString, QVariant>. |
| David Brown <david.brown@hesbynett.no>: Aug 29 10:24AM +0200 On 29/08/2019 02:58, James Kuyper wrote: > The part numbers are sequential in the order that the parts should occur > in. They are sent out sequentially, but in general, they don't arrive > sequentially. They are 1-based, not 0-based. I would expect that while the parts /could/ arrive out of order, they will come mostly roughly in-order. Since you know how many parts you will get (once you have received one part), and you know the part numbers are all 1 .. n, it seems strange to me that you have a map at all. I'd expect to use a vector, pre-allocated to the right size when the first part of a new message arrives. Perhaps you'd want the vector elements to be optional<string>, or just have empty strings for parts that haven't yet arrived. You might also want to track a counter of "parts waiting" so that you can easily see that the last part has arrived, without running through the vector. > having trouble figuring out how to word an inquiry that doesn't make it > sound like I think he wrote something stupid (since, in fact, that is > what I'm thinking). There are other possibilities for this odd data structure - other than stupidity or inexperience. It could be that the requirements or planned handling system changed underway - maybe the parts had a different identification system originally rather than simple integers. It could be that the code was prototyped in a more dynamic language, such as Python, or at least one where "variant" types are more common, such as Visual Basic, and the code then got translated into C++. And of course it could have been written under inhumane deadlines in the small hours of the night while overdosed on coffee and cold pizza - a lot of odd code has been written in such circumstances. > have let me work on something this low in priority if I weren't > currently stuck between a project I've finished and a project I'm not > allowed to start work on (we're waiting for approval from the client). Inefficiency is often not a huge problem - incorrectness is. |
| James Kuyper <jameskuyper@alumni.caltech.edu>: Aug 29 10:05AM -0400 On 8/29/19 4:24 AM, David Brown wrote: > On 29/08/2019 02:58, James Kuyper wrote: ... >> sequentially. They are 1-based, not 0-based. > I would expect that while the parts /could/ arrive out of order, they > will come mostly roughly in-order. That was my expectation, too. Reality didn't cooperate. During debugging, I never saw the parts arrive in strict sequential order, and they often arrived completely jumbled. Sometimes, for small messages, the final part would be the first one to arrive. That triggered another bug, but I've simplified my explanation of the code too much to explain why without adding a lot more details. Suffice it to say that the author apparently expected the final part to always be the one that arrived last - despite the fact that, if the parts were guaranteed to arrive in order, he could have simply appended each part to a string containing the parts that had already been received. That bug didn't puzzle me as much as the other issues I've mentioned, which is why I didn't mention it. > might also want to track a counter of "parts waiting" so that you can > easily see that the last part has arrived, without running through the > vector. I thought about the vector approach, but with the map approach, the size() member serves as parts_received, and the total count of parts is received with every part, so parts_waiting is just the difference. With the vector approach I'd have to keep track of one additional quantity (either parts_received, as I thought, or parts_waiting, per your suggestion). That adds just a little additional complexity, but enough to discourage me from using that approach. ... > identification system originally rather than simple integers. It could > be that the code was prototyped in a more dynamic language, such as > Python, or at least one where "variant" types are more common, such as That's plausible - some parts of this project are written in python. ... >> currently stuck between a project I've finished and a project I'm not >> allowed to start work on (we're waiting for approval from the client). > Inefficiency is often not a huge problem - incorrectness is. The code is incorrect, but cases which trigger the bug are extremely unlikely. With the inefficiency being small, and the incorrectness unlikely, this is justifiably a low-priority bug. I definitely have more important things to work on as soon as the work gets approved (I was investigating one of those more important things when I found this bug). |
| usenet@stegropa.de (Stefan Große Pawig): Aug 29 08:14PM +0200 [some context restored] >> and the QVariant values were filled in with part maps of the type >> QMap<QString, int>. I successfully changed the message map to > Correction: QMap<QString, QVariant>. But then, IIUC, that fits the bill: the QMap<QString, QVariant> for the parts /was/ stored in another QVariant (namely, as the value type of the message map). If the code used QVariant::value() to fetch the part map from the message map, there is no restriction on the type of the part map. The restriction only arises if the caller used QVariant::toMap(). Regardless of what the code originally used, maybe the original author had just scanned the QVariant interface for anything related to maps, found only the QMap<QString, QVariant> as baked-in return value and then assumed that this was the only map type that could be stored in a QVariant? -Stefan |
| Jorgen Grahn <grahn+nntp@snipabacken.se>: Aug 29 09:58AM On Wed, 2019-08-28, Richard wrote: > approach that many people have tried and failed. It's a really awful > idea. That suggestion should not be left out in the open > unchallenged. Yes, that was also worth pointing out, for other readers. /Jorgen -- // Jorgen Grahn <grahn@ Oo o. . . \X/ snipabacken.se> O o . |
| Jorgen Grahn <grahn+nntp@snipabacken.se>: Aug 29 06:09AM On Wed, 2019-08-28, Ruki wrote: >> excellent reason.) > Not all os provide spinlocks, and like nginx, they also use their > own spinlock implementation. I note that that doesn't really answer David's question. Weird that nginx implements spinlocks, when it also advertises itself as single-threaded. I don't see the use of spinlocks in a situation where there's only one thread of execution. /Jorgen -- // Jorgen Grahn <grahn@ Oo o. . . \X/ snipabacken.se> O o . |
| Tim Rentsch <tr.17687@z991.linuxsc.com>: Aug 28 06:03PM -0700 "Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com> writes: I have now carefully read through all your responses in the cascade of messages downstream of my message two upthread. > I may address the rest of your posting later, trying to give the > examples etc. you ask for, because I feel you mean this seriously. I do mean it seriously, and not at all confrontationally. I am interested to read your further followup (ie, as mentioned above) if you choose to post one. > And I don't think you think you're smarter than everybody else in > this group just for holding an opinion on UB that nobody else here > shares. For the most part I don't think about whether I am smarter than any particular person, let alone everyone in the group, partly because "smart" is a multi-dimensional quantity, and it's very rare (if indeed it has ever happened at all) that I find a person where I think I am smarter along all axes. Even if it were true that my opinion on a subject were not shared by any other contributor in the group, that would not affect my sense of what "smarter" means. > I think you're simply convinced that you're right, In my view the word "right" does not apply, because I take both of our statements as expressing opinions about how the standards "should" be interpreted. Opinions are never right or wrong, they just are whatever they are. > that your distinctions are meaningful, I do think the distinctions I have been trying to explain are meaningful. > and somehow my and others' arguments have failed to move your > conviction. I think an essential first step is missing. For my views to change as a result of what you say (or vice versa), I must first understand what you mean and why you think what you do (similarly vice versa). Right now I think we are not understanding each other. Key example: the term "undefined behavior". Even though we both use the term "undefined behavior", I think what you mean by the term is not the same as what I mean by it. If that is so then obviously it gets in the way of us communicating. Normally in discussions like this one, my efforts are directed at trying to convey what I think and why, and not to try to convince the other participant(s) to change their minds. > Which I think means we're not good enough at presenting our > view. Not, that we're wrong. ;-) Again, I don't think either of our views is right or wrong. I agree though that explaining what it is you think should be given more emphasis than trying to convince me that you're right. |
| 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