- Anyone working with Graphiz and DOT (directed graphs) - 2 Updates
- All function declarations/defintions and variable declaration/defintions one one line - 3 Updates
- ""Rust is the future of systems programming, C is the new Assembly": Intel principal engineer, Josh Triplett" - 5 Updates
- Order of designated initializers in C++20 - 4 Updates
- Static_assert in 2017 C++ - 8 Updates
- Performance of exceptions - 3 Updates
| Frederick Gotham <cauldwell.thomas@gmail.com>: Sep 02 03:27AM -0700 > > try { p_children = &g_links.at(str_parent); } catch (...) { return; } // The method 'at' will throw if no such key exists in the map > You shlouldn't catch this it is fatal error. Are you saying that a 'map' object is unusable after a failed attempt to use 'at' ? |
| David Brown <david.brown@hesbynett.no>: Sep 02 09:58PM +0200 Please quote properly, without snipping attributions. On 02/09/2019 12:27, Frederick Gotham wrote: >> You shlouldn't catch this it is fatal error. > Are you saying that a 'map' object is unusable after a failed attempt to use 'at' ? I suspect he means that a failed "at" generally means you have a bug in your code as you are trying to access something that doesn't exist. So rather than catching the exception and trying to recover, you should use the exception information as an aid to finding and fixing the bug. |
| Frederick Gotham <cauldwell.thomas@gmail.com>: Sep 02 03:30AM -0700 For the past 17 years, I've become accustomed to reading function declarations like this: int MyFunc(double x); I'm working on a project now though where there's function declarations like this: int MyFunc (double x); I've tried a few different code beautifiers and none of them can turn this into a one-liner. Anyone got a tool for this? |
| Barry Schwarz <schwarzb@dqel.com>: Sep 02 11:25AM -0700 On Mon, 2 Sep 2019 03:30:31 -0700 (PDT), Frederick Gotham > (double x); >I've tried a few different code beautifiers and none of them can turn this into a one-liner. >Anyone got a tool for this? If you tell us which tools you have already tried, you might receive more useful responses. -- Remove del for email |
| Bonita Montero <Bonita.Montero@gmail.com>: Sep 02 08:32PM +0200 > int > MyFunc > (double x); I would acceppt any common style, but this is idiotic. |
| Richard Damon <Richard@Damon-Family.org>: Sep 02 11:12AM -0400 On 9/2/19 12:47 AM, Bonita Montero wrote: >> maybe it is. > We're not discussing about error handling or not; > wer're discussing the performance-impacts. Yes, we are talking about the performance impact of error handling. >> requirements. > You don't have any clue what you're talking about. > You simply fantasizing to emphasize your authority. As an example, lets take sending data to the flight recorder in an airplane. Errors may well occur during this operation (perhaps one log fills so you need to switch to another). There may well be a piece of this in the critical control loops. If an error delays the loop, then perhaps some critical function fails, perhaps causing a loss of control of the system. Likely the critical control loop isn't directly communicating with the flight recorder, but with an intermediary operation to provide some buffering, but if the intermediary operation gets delayed too much in sending the data to the flight recorder, it might not service the control loop fast enough, causing the problems. I don't work on airplanes (but I do work with real time systems), so this exact case may not apply, but is a fairly graphic one which shows that in a real time system, even errors need to be handled within time limits. People who are used to 'PC' or 'Server' Class machines often don't understand the real time world, On the PC 0.1 second response is often good enough, maybe with a real-time interactive game it goes down to 0.01 seconds, and not meeting that time mark is just a minor 'performance' issue. In a true real time system the time period is often much shorter, and the cost of not meeting the time requirements are often much more significant, something stopped working. |
| Bonita Montero <Bonita.Montero@gmail.com>: Sep 02 05:52PM +0200 > this in the critical control loops. If an error delays the loop, then > perhaps some critical function fails, perhaps causing a loss of control > of the system. Such systems have their critical resources allocated at startup that those situations don't occur. |
| Manfred <noname@add.invalid>: Sep 02 06:43PM +0200 On 9/2/2019 5:52 PM, Bonita Montero wrote: >> of the system. > Such systems have their critical resources allocated at startup that > those situations don't occur. You really can't get it, can you? |
| Richard Damon <Richard@Damon-Family.org>: Sep 02 01:05PM -0400 On 9/2/19 11:52 AM, Bonita Montero wrote: >> of the system. > Such systems have their critical resources allocated at startup that > those situations don't occur. Out of Resources is not the only type of error that typcially generates an exception. Some would have critical I/O errors be reported back as exceptions (Remember the original discussion was Exceptions vs testing return values). If one write in a billion might generate the error condition, by many people that would be considered 'exceptional' and properly done with an exception. On a PC, if once every billion operations we got a slight additional delay to the user, that would be normally acceptable. If that one in a billion causes your airplane engine to stall in mid air, it wouldn't be. |
| Bonita Montero <Bonita.Montero@gmail.com>: Sep 02 07:33PM +0200 > Out of Resources is not the only type of error that typcially generates > an exception. Some would have critical I/O errors be reported back as > exceptions .. Have you considered the part of such an I/O-operation that might fail is the kernel-call that has a higher processing-overhead than the error -handling itself? |
| Juha Nieminen <nospam@thanks.invalid>: Sep 02 09:44AM In C you can use designated initializers to initialize a struct (or an array). There is no requirement for the order in which the initializers are listed, so it's completely ok to list them in a different order than they are declared in the struct. So you can have: struct S { int a, b; }; struct S s = { .b = 1, .a = 2 }; In C++20, however, you cannot list the initializers in the "wrong" order. Why? It would be highly convenient that designated initializers wouldn't need to be in the same order as the variables declared in the struct. For example, the variables may be declared in one order in the struct based on efficiency (the order of member variables may affect the size of the struct), but listed in an initialization in another, eg. grouped logically based on role. Moreover, and more importantly, later changing the order of the variables in the struct will not break the initialization (which I think is one of the main motivations for it having been introduced in the first place). Why does C++20 impose this restriction? I understand that C++ wants to initialize member variables in the order they are declared inside the struct/class. However, I don't see why this should affect designated initializers. If listing the designated initializers in the "wrong" order is some kind of problem when it comes to initialization values with side-effects, the standard could simply state that if the designated initializers are not listed in the same order as declared in the struct, the order of evaluation of the values is not guaranteed and implementation-defined. However, it doesn't need to outright forbid it. (After all, there are other situations as well, where order of evaluation is not guaranteed, such as when giving parameters to a function.) I don't know what the C standard says about what happens when designated initializers are not in the same order as in the declaration of the struct, but at least clang seems to simply evaluate the values in the same order as the latter, so it doesn't seem to be a problem. |
| James Kuyper <jameskuyper@alumni.caltech.edu>: Sep 02 10:20AM -0400 On 9/2/19 5:44 AM, Juha Nieminen wrote: > struct S s = { .b = 1, .a = 2 }; > In C++20, however, you cannot list the initializers in the "wrong" > order. ... > I don't know what the C standard says about what happens when designated > initializers are not in the same order as in the declaration of the struct, I can't answer your other questions, but I can answer that one. This is no such restriction in C on the order in which designators are written, and here's what C2011 says about the order in which the resulting initializations occur: "... When no designations are present, subobjects of the current object are initialized in order according to the type of the current object: array elements in increasing subscript order, structure members in declaration order, and the first named member of a union. In contrast, a designation causes the following initializer to begin initialization of the subobject described by the designator. Initialization then continues forward in order, beginning with the next subobject after that described by the designator." (6.7.8p17). Thus, a designation causes a jump in the initialization order, after which initialization moves forward as normal from the new position. You could, as a result, end up initializing the same element or an array, or the same member of a struct, multiple times. I would expect to see such code only in the obfuscated C contest or in machine generated code, but it is permitted. |
| Paavo Helde <myfirstname@osa.pri.ee>: Sep 02 05:25PM +0300 On 2.09.2019 12:44, Juha Nieminen wrote: > initializers are not in the same order as in the declaration of the struct, > but at least clang seems to simply evaluate the values in the same order > as the latter, so it doesn't seem to be a problem. So you propose that code pieces should be evaluated at a different order than written. We already have a bad case of such silent code reordering with the initialization lists, the committee probably did not want to repeat that mishap. |
| Bonita Montero <Bonita.Montero@gmail.com>: Sep 02 05:13PM +0200 > struct S s = { .b = 1, .a = 2 }; > In C++20, however, you cannot list the initializers in the "wrong" > order. I think this does help to read the initialization of a structure because you can read it in the order as it is defined in the structure. So if you read the initialization and have the defi- nition open in another window, that's a more convenient read- ability. > based on efficiency (the order of member variables may affect the > size of the struct), but listed in an initialization in another, eg. > grouped logically based on role. Convenience isn't determined in efficiency. And if you won't have a POD you can't rely on a certain layout anyway. > variables in the struct will not break the initialization (which > I think is one of the main motivations for it having been introduced > in the first place). Ok, that's a proper reason; but as I said above, this would lead to less readable code because the inizialization isn't synchronous with the definition. |
| Bonita Montero <Bonita.Montero@gmail.com>: Sep 02 08:33AM +0200 > read all... > https://groups.google.com/forum/?hl=en#!original/comp.arch/JkcTGC9X3lo/M4Vo_cXKEwAJ > Still, create a new post over on comp.arch I further don't believe this; check this: https://bit.ly/2lprsvC You won't find his full name this. I'm pretty sure that his full name would be known you would easily google it; but you can't. You have a very impulsive kind of thinking or you are very impulsive at at all according to your posting-behaviour. |
| "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com>: Sep 02 12:18AM -0700 On 9/1/2019 11:33 PM, Bonita Montero wrote: > name would be known you would easily google it; but you can't. > You have a very impulsive kind of thinking or you are very > impulsive at at all according to your posting-behaviour. Post over on comp.arch. Anne & Lynn Wheeler might still be watching it. |
| Bonita Montero <Bonita.Montero@gmail.com>: Sep 02 09:23AM +0200 >> You have a very impulsive kind of thinking or you are very >> impulsive at at all according to your posting-behaviour. > Post over on comp.arch. Anne & Lynn Wheeler might still be watching it. That's not necessary. If there would be a definite name you could easily google it. -- http://facebook.com/bonita.montero/ |
| "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com>: Sep 02 12:26AM -0700 On 9/2/2019 12:23 AM, Bonita Montero wrote: >> Post over on comp.arch. Anne & Lynn Wheeler might still be watching it. > That's not necessary. > If there would be a definite name you could easily google it. I cannot do it. |
| David Brown <david.brown@hesbynett.no>: Sep 02 01:13PM +0200 On 02/09/2019 07:16, Bonita Montero wrote: >>> Maybe, but your style of response isn't mature. >> Neither is deliberately snipping attributions... > You're right. I will go to the psychotherapist because of that !!!!!!!!! No, you won't. You will just be ignored. |
| Bonita Montero <Bonita.Montero@gmail.com>: Sep 02 03:55PM +0200 >> You're right. I will go to the psychotherapist because of that !!!!!!!!! > No, you won't. You will just be ignored. That's your hope because you want this to be sanctioned. But this won't fulfill. |
| woodbrian77@gmail.com: Sep 02 07:32AM -0700 > OK, you meant should a *message* be used (not a comment) in the static > assertion (at least in C++17, where the message is now optional). > Obviously it depends on the context. OK. Thanks for the correction. |
| Jorgen Grahn <grahn+nntp@snipabacken.se>: Sep 02 02:43PM On Sun, 2019-09-01, Richard Damon wrote: >> http://webEbenezer.net > Personally, I would be tempted to leave it as is. Making useful error > messages is generally good. I have a thing against assert(condition, message) in general, so I'd drop it, if static_assert(std::numeric_limits<float>::is_iec559); is likely to be meaningful to the reader, after some googling. However, in an earlier discussion here, years ago, most didn't feel that way. > Making the Error comment optional might make > some sense if the Error Condition is fully self documenting, but the > linkage between IEC559 and IEEE754 isn't inherently obvious. If it's hard to make the condition self-documenting, there should be a message. Even I can agree to that. /Jorgen -- // Jorgen Grahn <grahn@ Oo o. . . \X/ snipabacken.se> O o . |
| Bonita Montero <Bonita.Montero@gmail.com>: Sep 02 08:56AM +0200 I posted some code here in the Rust-thread which measures the performance of throwing an excetion. I made a mistake in the first place because I didn't consider the slow-down of a x264 -thread on the same core. So the "performace" was a bit sur- prising and a throw of an int took about 3 million clock-cycles. As I ran it without any load a throw took about 8.6000 clock -clycles on my Ryzen 7 1800X. I told that I'm curious about the performance of other imple- mentations (although this isn't really practically relevant). I further improved my code to have two cases: 1. An exception of a base-class is trown and the base-class is catched. 2. An exception of a class derived from a class derived from the base-class is thrown and the base-class is catche. In this case the difference in performance results from the matching of the base-class. Maybe some readers haven't read so deeply into the Rust-thread so that only a few had read my posting. So I'm trying it for a last time to encourage the readers to modify the code for their compilers to get different results. This is the common header: #pragma once #include <exception> void BaseThrower(); void DerivedBThrower(); struct ExcBase : public std::exception { }; struct ExcDerivedA : public ExcBase { }; struct ExcDerivedB : public ExcDerivedA { }; This is the translation-unit with the trowing functions: #include "exc.h" void BaseThrower() { throw ExcBase(); } void DerivedBThrower() { throw ExcDerivedB(); } This is the main translation-unit: #include <windows.h> #include <iostream> #include <intrin.h> #include "exc.h" using namespace std; typedef long long LL; LL Benchmark( void (*thrower)(), unsigned const rep ); int main() { // to get always the same TSC SetThreadAffinityMask( GetCurrentThread(), 1 ); unsigned const REP = 1'000'000; LL ticks; ticks = Benchmark( BaseThrower, REP ); cout << "BaseThrower: " << (double)ticks / REP << endl; ticks = Benchmark( DerivedBThrower, REP ); cout << "DerivedBThrower: " << (double)ticks / REP << endl; } LL Benchmark( void (*thrower)(), unsigned const rep ) { LL start = (LL)__rdtsc(); for( unsigned i = rep; i; --i ) try { thrower(); } catch( ExcBase & ) { } return (LL)__rdtsc() - start; } So I would be pleased about any results. |
| Bonita Montero <Bonita.Montero@gmail.com>: Sep 02 09:02AM +0200 BTW: I know that actual CPUs support invariant time-stamp -counters. So as the clock of the CPU might boost here the TSC wouls still count at a constant rate. But my code will still get a rough estimate of the overhead throwing an exception. |
| Bonita Montero <Bonita.Montero@gmail.com>: Sep 02 11:34AM +0200 I just modified the main source to be not dependent on Windows: #include <iostream> #include <intrin.h> #include <chrono> #include "exc.h" using namespace std; using namespace std::chrono; typedef long long LL; LL Benchmark( void (*thrower)(), unsigned const rep ); void SetAffinityToFirstThread(); int main() { unsigned const REP = 1'000'000; LL ns; ns = Benchmark( BaseThrower, REP ); cout << "BaseThrower: " << (double)ns / REP << "ns" << endl; ns = Benchmark( DerivedBThrower, REP ); cout << "DerivedBThrower: " << (double)ns / REP << "ns" << endl; } LL Benchmark( void (*thrower)(), unsigned const rep ) { time_point<high_resolution_clock> start = high_resolution_clock::now(); for( unsigned i = rep; i; --i ) try { thrower(); } catch( ExcBase & ) { } return (LL)duration_cast<nanoseconds>( high_resolution_clock::now() - start ).count(); } |
| 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