- Don't be fooled by cpp.sh - 7 Updates
- C++ threshold for "stupid" sorting algorithms (O(n^2)) - 2 Updates
- Union type punning in C++ - 4 Updates
- little contest - 1 Update
- Wading through template instantiation errors for allocator - 2 Updates
- How to overload get<>() ? - 2 Updates
Tim Rentsch <tr.17687@z991.linuxsc.com>: Jan 10 08:10AM -0800 > On 31.12.2019 19:46, Bonita Montero wrote: [...] >> This would be disturbing if you would have the function in the >> code for a later purpose. > So you are checking in untested code. On the contrary, such unused functions are completely tested: any function that is never called cannot possibly misbehave. The warning message saying the function is unused is the success indicator for testing the function in question. It is only functions that are called that might contain program errors. |
Tim Rentsch <tr.17687@z991.linuxsc.com>: Jan 10 08:29AM -0800 > (The word "may" is a bit ambiguous, and it could be argued that an > implementation isn't required to support constants of type int128_t > even if it's an extended integer type.) Not really convincingly. The end of that paragrah says If an integer constant cannot be represented by any type in its list and has no extended integer type, then the integer constant has no type. I don't see any sensible way of reading those sentences together and concluding that using an extended integer type is allowed to be optional. |
Tim Rentsch <tr.17687@z991.linuxsc.com>: Jan 10 08:46AM -0800 > So the footnote effectively asserts that its conclusions are implied > by normative rules, though it's not clear that there's any normative > text in the C standard that supports the claim in this footnote. In my reading of the C standard, there is normative text that establishes the assertion in the footnote. > If the normative requirements in C++ are sufficiently similar to > those in C, one could argue that the assertion in that footnote is > as valid for C++ as for C. The C++ standard clearly does not admit the same reasoning as the C standard in this regard, because the definedness of accessing union members is tied (in C++) to their lifetimes, and the lifetimes are not the same in C++ as they are in C. In C++, the "UB-ness" of accessing a different union member can be established constructively (ie, it is not just a question of a definition being omitted). > (My own conclusion is that the lack of supporting normative text is a > flaw in the C standard. It should make a clear normative statement > about the behavior of type punning using union members.) There is normative text that implies what the footnote says. That isn't as obvious as some people might like, so it would be good if the behavior were described more directly, for clarity. But the behavior is described more directly: it is described in this very footnote. |
Keith Thompson <Keith.S.Thompson+u@gmail.com>: Jan 10 09:51AM -0800 > Keith Thompson <Keith.S.Thompson+u@gmail.com> writes: [...] >> text in the C standard that supports the claim in this footnote. > In my reading of the C standard, there is normative text that > establishes the assertion in the footnote. Do you have some reason for not telling us where that normative text is? I know this is comp.lang.c++, but I suggest that the presence of such text in the C standard, and its absence in the C++ standard, is relevant to C++. > "UB-ness" of accessing a different union member can be established > constructively (ie, it is not just a question of a definition > being omitted). Please consider telling us *how* it can be established constructively rather than just being vague. [...] -- Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com [Note updated email address] Working, but not speaking, for Philips Healthcare void Void(void) { Void(); } /* The recursive call of the void */ |
Tim Rentsch <tr.17687@z991.linuxsc.com>: Jan 10 02:19PM -0800 Robert Wessel <robertwessel2@yahoo.com> writes: [...] > VLAs present considerable implementation difficulties on some > small systems, Do you mean small in the sense of limited resources? Or small in the sense of not having a full hosted library? What problems are there in these small systems that don't come up in larger systems? > and present a number of issues with regards to stack growth on all > implementations VLAs may present some issues with regard to stack growth, but they don't have to. The Standard admits implemenations that put VLAs somewhere other than on the stack, eg, allocated with malloc(). |
Tim Rentsch <tr.17687@z991.linuxsc.com>: Jan 10 02:51PM -0800 > route). "Minimal" or "trivial" library, probably. > Or you implement creal and cimag as macros (implementation dependent, > but trivial, in most cases). These functions can be done completely portably for any implementation that has _Complex. Here are the 'double' versions: double creal( _Complex double z ){ return (union { _Complex double z; double dd[2]; }){ z }.dd[0]; } double cimag( _Complex double z ){ return (union { _Complex double z; double dd[2]; }){ z }.dd[1]; } |
Tim Rentsch <tr.17687@z991.linuxsc.com>: Jan 10 02:59PM -0800 > text is? I know this is comp.lang.c++, but I suggest that the > presence of such text in the C standard, and its absence in the C++ > standard, is relevant to C++. I didn't have time for a longer posting. Also I don't think it's relevant for C++ because there is additional text in the C++ standard that explicitly makes such accesses be undefined behavior. >> being omitted). > Please consider telling us *how* it can be established constructively > rather than just being vague. My comments were consciously incomplete, but I don't think it's fair to call them vague, just incomplete. In any case I will try to post a more complete explanation sometime soon, in comp.lang.c. |
Tim Rentsch <tr.17687@z991.linuxsc.com>: Jan 10 01:53PM -0800 > Generally the O(n**2) sorts are considered usable up a few tens of > items. And use insertion sort, not bubble sort (simpler algorithm, > twice as fast on average). The simplest bubble sort is simpler than the simplest insertion sort. The most complete bubble sort is simpler than the most complete insertion sort. It is only if we compare a somewhat less complete rendition of insertion sort to a somewhat more complete rendition of bubble sort that "insertion sort" may be called simpler. I agree that insertion sort is a better choice than bubble sort in almost all cases, but saying insertion sort is simpler than bubble sort is an apples-and-oranges comparison. |
Robert Wessel <robertwessel2@yahoo.com>: Jan 10 04:45PM -0600 On Fri, 10 Jan 2020 13:53:52 -0800, Tim Rentsch >I agree that insertion sort is a better choice than bubble sort >in almost all cases, but saying insertion sort is simpler than >bubble sort is an apples-and-oranges comparison. For common definitions of what bubble and insertion sorts are, insertion sorts are simpler. Standard versions in C: void InsertionSort(int a[], int length) { int i, j, temp; for(i = 1; i < length; i++) { temp = a[i]; for (j = i - 1; j >= 0 && a[j] > temp; j--) a[j + 1] = a[j]; a[j] = temp; } } void BubbleSort(int a[], int length) { int i, j, temp; for (i = 0; i < length; i++) { for (j = 0; j < length - i - 1; j++) { if (a[j + 1] < a[j]) { temp = a[j]; a[j] = a[j + 1]; a[j + 1] = temp; } } } } There's not a lot of difference there (basically all the same lines of code, except that the "if" in the bubble sort has been folded into insertion sort's inner loop termination test). But there's little to add to the insertion sort, while the bubble sort is usually enhanced by adding a check to stop if no swapping has been done in a pass, adding more code (and if you don't, the usual claim that bubble sort works well on already sorted files is false). If you do the swap test in bubble sort you can simplify the outer loop, but a fair cost in performance for unsorted inputs. Enhancement to both are possible (if somewhat pointless), but often result in what's usually considered a different sort. Using a binary search to determine the insertion point, or working the bubble sort from both ends result in binary insertion and cocktail shaker sorts, for example. |
Mister2U@honorific.org: Jan 10 12:28PM On Thu, 9 Jan 2020 12:59:29 -0800 (PST) >But if it may refuse to work until all floats are received then >I probably would copy half but would throw after timeout >destroying all the received floats and not processing anyway. These sort of problems are why any genuine network programmer always includes the expected packet size in a stream packet (usually at the beginning) instead of doing something stupid like sending raw XML or json on its own where constant parsing is required to see if the end of the data has been reached yet and may get it wrong if the formatting is bad and continue waiting for data beyond the end. For UDP where data send in a single write is returned in a single read that approach is fine, not so for TCP. Sadly a new generation of programmers has yet to figure this out. |
David Brown <david.brown@hesbynett.no>: Jan 10 02:02PM +0100 >> I probably would copy half but would throw after timeout >> destroying all the received floats and not processing anyway. > These sort of problems are why any genuine network programmer always includes This is a matter of protocol design, not programming. Any "genuine network programmer" writes code to handle the protocol specified - whether it includes a packet size or not. Protocols where the length of the telegram is given either explicitly in a header, or implied from the protocol type, make reception simpler. But they can involve more work when generating the data. There is a trade-off here, and it is not as simple as saying one method is always best. (Having said that, I prefer to give the length explicitly when designing protocols.) > beyond the end. For UDP where data send in a single write is returned in a > single read that approach is fine, not so for TCP. Sadly a new generation of > programmers has yet to figure this out. Some protocols on top of TCP/IP or UDP, such as MQTT, have length fields in the telegrams. For JSON, a very simple solution is to use newline-delimited JSON - you send the JSON string, then a linefeed character. It's easy to see when you have the whole string, because you have found a character 10, and can then start parsing. I think it would be nice to see more use of SCTP, which combines the benefits of TCP/IP and UDP - letting you get the "datagram" feature of UDP while also getting the guarantees and fragmentation control of TCP/IP. But it is not well supported in common routers (or Windows), making it a lot harder to establish it for common use. |
Mister2U@honorific.org: Jan 10 04:21PM On Fri, 10 Jan 2020 14:02:38 +0100 >This is a matter of protocol design, not programming. Any "genuine >network programmer" writes code to handle the protocol specified - >whether it includes a packet size or not. Well yes, but I was talking about when designing one. >send the JSON string, then a linefeed character. It's easy to see when >you have the whole string, because you have found a character 10, and >can then start parsing. That'll work fine - until you have ascii 10 inside a quoted string which is entirely plausible. The same problem exists if doing simple curly bracket counting. Its a non trivial problem and shouldn't be something the network layer has to worry about. >I think it would be nice to see more use of SCTP, which combines the Unfortunately SCTP is de facto dead. It was a good attempt but didn't get the traction. |
David Brown <david.brown@hesbynett.no>: Jan 10 07:18PM +0100 > entirely plausible. The same problem exists if doing simple curly bracket > counting. Its a non trivial problem and shouldn't be something the network > layer has to worry about. No, it is not plausible - you can't have ASCII 10 in the JSON string. It must be escaped as "\n". >> I think it would be nice to see more use of SCTP, which combines the > Unfortunately SCTP is de facto dead. It was a good attempt but didn't get the > traction. Exactly. |
Tim Rentsch <tr.17687@z991.linuxsc.com>: Jan 10 07:44AM -0800 Jorgen Grahn <grahn+nntp@snipabacken.se> writes: [...] > I always assumed parsing meant reading any kind of data, deciding if > it matches the parser's language, and if it does, offering the > "pieces" in a helpful way to the next step of processing. This description is consistent with my own understanding and also with the various definitions and other online resources I consulted. > E.g. yacc is a parser generator, but in my mind so is scanf(). I wouldn't say scanf() is a parser generator, because it doesn't generate a parser but rather goes ahead and does (some) parsing. Perhaps more significantly, usually scanf() is used to parse not an entire language but only some part of an input, with other calls to scanf() parsing other parts of the input (and hence other parts of the language being accepted). To me scanf() is closer to being a lexer than a parser. However these are minor distinctions; it's fair to say that a scanf() call parses a line (or some other part) of an input. > (And as background: I know for sure I was taught in computer science > that "language" is anything with a syntax and (I suppose) semantics. > It doesn't have to be Turing-complete or anything.) In formal Computer Science, a language is any set of strings over a finite alphabet. In most cases we are concerned only with those languages that can be recognized by a computer program, and so necessarily have a finite (and well-defined) "grammar". I put the word "grammar" in quotes only because computer programs are more varied than what is generally meant by the word grammar. By themselves languages are just sets of strings, and do not have any associated semantics. However it is certainly right that a language needn't be large or "complete" in any sense. The set of strings { "cat", "dog" } qualifies as a language in formal language theory. > [...] I tend to do things which fit in Unix pipelines. (Comment about English language usage only.) In English, this sentence is better written using "that" in place of "which". The reason is the word "that" is restrictive, whereas the word "which" is non-restrictive. That should be enough so you can read a more full description somewheres on the web. (Or if not ask and I will try to track down a good reference.) (Note: my comment is meant only to be helpful, not corrective. My friends for whom English is not their first language tell me it's helpful for them to hear remarks like this, so their English can be better. That's all I'm trying to do here.) |
Tim Rentsch <tr.17687@z991.linuxsc.com>: Jan 10 06:48AM -0800 > On 04/01/2020 04:04, Frederick Gotham wrote: >> auto main(void) -> int > What kind of an abomination is this? As abominations go, it's one of the best. |
Tim Rentsch <tr.17687@z991.linuxsc.com>: Jan 10 07:06AM -0800 >>> What kind of an abomination is this? >> It fails to compile on older C++ compilers, before C++11 > It should fail to compile with compilers that enforce good taste. So, not on any currently conforming C++ compiler, you mean? |
boltar@nowhere.org: Jan 10 12:18PM On Thu, 9 Jan 2020 12:42:23 -0800 (PST) >The std::tuple is variadic template and so its elements are >enumerated during its generation. For such stinky myclass it >is most trivial to make those manually. If quite capable of writing a class method called get() though I wouldn't use such a ridiculously complex method that you have, I wanted to how to use the standard library get() for my classes as per tuple and variant. It can be done with a tuple cast overload method in the class but unfortunately when using get() it requires an explicit cast in the call. eg: auto val = get<0>((tuple<string,int,int>)(myobj)); Which works but is ugly. |
guinness.tony@gmail.com: Jan 10 07:04AM -0800 > : > }; > cout << get<0>(obj); <- How would I make this return string s for example? I have presumed (as Öö Tiib also did) that you actually want the mapping get<0>(obj) <=> obj.b get<1>(obj) <=> obj.i get<2>(obj) <=> obj.s The following function templates did the trick for me. The second one also facilitates lvalue access (just as the std::get<>() function templates do), so you can perform indexed-member assignments, e.g. get<2>(obj) = "foo"; ---- 8< ---- #include <tuple> template<std::size_t I> constexpr auto const& get(myclass const& obj) { return std::get<I>(std::tie(obj.b, obj.i, obj.s)); } template<std::size_t I> constexpr auto& get(myclass& obj) { return std::get<I>(std::tie(obj.b, obj.i, obj.s)); } |
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