- [Modération JNTP] Annulation de <q2585b$j8e$7@dont-email.me> - 1 Update
- AddressSanitizer workflows? - 3 Updates
- I have just read the following about Rust programming language - 1 Update
- "Is C++ fast?" - 10 Updates
- On adapting an iterator - 3 Updates
- What is clean code? - 1 Update
Elephant Man <conanospamic@gmail.com>: Jan 21 09:59PM Article d'annulation émis par un modérateur JNTP via Nemo. |
Daniel <danielaparker@gmail.com>: Jan 21 07:16AM -0800 On Saturday, January 19, 2019 at 5:37:56 AM UTC-5, Jorgen Grahn wrote: > - Which sanitizers do people enable, as a rule? > - When do you use them? I suppose at least when running unit and > component tests. Does anyone use them in production? I had a user of an open source library I'm the author of report a "misaligned address" warning when parsing CBOR (binary format.) It came down to a use of reinterpret_cast (undefined behavior) rather than memcpy (correct behavior), even though the generated assembly happened to be the same, and the code ran. Since then I've always run travis integration builds with -fsanitize=address -fsanitize=undefined. Daniel |
Jorgen Grahn <grahn+nntp@snipabacken.se>: Jan 21 04:34PM On Mon, 2019-01-21, Daniel wrote: > down to a use of reinterpret_cast (undefined behavior) rather than memcpy > (correct behavior), even though the generated assembly happened to be the > same, and the code ran. I assume that's -fsanitize=undefined warning about something that will work on x86, but crash and burn on e.g. PPC? That's a nice feature; I'm not sure valgrind will warn about that at all. > Since then I've always run travis integration builds > with -fsanitize=address -fsanitize=undefined. /Jorgen -- // Jorgen Grahn <grahn@ Oo o. . . \X/ snipabacken.se> O o . |
Jorgen Grahn <grahn+nntp@snipabacken.se>: Jan 21 09:18PM On Mon, 2019-01-21, Öö Tiib wrote: >> but my code didn't seem to have those flaws, apart from a leak I knew >> about already. > I don't care about leaks (since with RAII there are virtually none anyway). In this case I was using a C library with confusing manual memory management[0] and hadn't wrapped it properly. But often you also want to run dynamic checkers on others' code to find out how ill-behaved it is; then leak checking is a useful feature IMO. > buffer overflows. >> - Which sanitizers do people enable, as a rule? > All of these but one at time. Address, leak and undefined, then. I see -fsanitize=thread too. The GCC manual says some of the sanitizers cannot be used together, but doesn't say which ones. > https://docs.microsoft.com/en-us/cpp/standard-library/checked-iterators?view=vs-2017 > These will typically detect if code misuses operators of containers > or iterators; ASan will detect if code misuses pointer arithmetics. Thanks; I (and others) tend to forget that option. /Jorgen [0] libxml2. I don't like the existing C++ wrapper, and wanted to see if I could do without it. Also, my program will exit a millisecond after parsing anyway ... -- // Jorgen Grahn <grahn@ Oo o. . . \X/ snipabacken.se> O o . |
Horizon68 <horizon@horizon.com>: Jan 21 11:56AM -0800 Hello... I have just read the following about Rust programming language: "What I'm going to discuss here is the choice made in Rust to disallow having multiple mutable aliases to the same data (or a mutable alias when there are active immutable aliases), even from the same thread. This is essentially the "Read-Write lock" (RWLock) pattern, except it's not being used in a threaded context, and the "locks" are done via static analysis (compile time "borrow checking")." Read more here: https://manishearth.github.io/blog/2015/05/17/the-problem-with-shared-mutability/ So as you are noticing that to avoid race conditions etc. Rust is using the Read-Write lock (RWLock) pattern , but i think this is not a fine-grained parallelism, so with the Read-Write lock (RWLock) pattern of Rust you are loosing fine-grained parallelism that gives much more parallelism. Also about Memory safety of Rust , we know that Memory safety that is the state of being protected from various software bugs and security vulnerabilities when dealing with memory access, such as buffer overflows and dangling pointers. And as you have noticed i think i have solved the problem of dangling pointers and i have solved the problem of memory leaks by "inventing" a reference counting with efficient support of weak references that is "scalable", and i think that this invention of mine is the only one that you will find, and you will not find it in C++ and you will not find it in Rust. Read about it in the following: My new "invention" that is an enhanced fully scalable algorithm is finished and is coming soon.. I have just enhanced "much" more my "invention" of a scalable algorithm of a scalable reference counting with efficient support for weak references, i think i am the only one who has invented this scalable algorithm, because it is the only one who is suited for non-garbage collecting languages such as C++ and Rust and Delphi, and i have just made my enhanced algorithm fully scalable on manycores and multicores and NUMA systems by using a clever scalable algorithm, so i think i will "sell" my new invention that is my enhanced scalable reference counting algorithm with efficient support for weak references and its implementation to Microsoft or to Google or to Intel or Embarcadero And about memory safety and memory leaks in programming languages.. Memory safety is the state of being protected from various software bugs and security vulnerabilities when dealing with memory access, such as buffer overflows and dangling pointers. I am also working with Delphi and FreePascal and C++, and as you have noticed i have invented a scalable reference counting with efficient support for weak references that is really powerful, read about it and download it from here(it is the Delphi and FreePascal implementation): https://sites.google.com/site/scalable68/scalable-reference-counting-with-efficient-support-for-weak-references And you have to understand that this invention of mine solves the problem of dangling pointers and it solves the problem of memory leaks and this reference counting of mine is also "scalable", and i think that this invention of mine is the only one that you will find, and you will not find it in C++ and you will not find it in Rust. Also Delphi and FreePascal detect the out of bounds in arrays and strings like this by making range checks enabled: In the {$R+} state, all array and string-indexing expressions are verified as being within the defined bounds, and all assignments to scalar and subrange variables are checked to be within range. **If a range check fails, an ERangeError exception is raised (or the program is terminated if exception handling is not enabled). Range Checks is OFF by default. To enable it, you can add this directive to your code: {$RANGECHECKS ON} You can use also generic (template) style containers for bound checking, my following writing to understand more: About C++ and Delphi and FreePascal generic (template) style containers.. Generics.Collections of Delphi and FreePascal for generic (template) style containers that you can download from here: https://github.com/maciej-izak/generics.collections TList of Generics.Collections of Delphi and FreePascal is implemented the same as STL C++ Vectors: they are array-based. And since data structureS are the same then also performance should be comparable. So I've done a small test between Tlist of Generics.Collections of Delphi and FreePascal and C++ vector, it's an addition of 3000000 records of 16 byte length, in one loop, here is the results: Tlist time = 344ms Vector time = 339ms It seems they are the same, the test use only the function ( List.add , vector.push_back). STL vectors with the at() and Delphi TList of Generics.Collections of Delphi and FreePascal perform bounds checking. So i think that with my invention above and with all my other inventions that are my scalable algorithms and there implementations and such in C++ and Delphi and FreePascal that you will find in my following website, Delphi and FreePascal have become powerful: https://sites.google.com/site/scalable68/ Thank you, Amine Moulay Ramdane. |
fir <profesor.fir@gmail.com>: Jan 21 06:08AM -0800 W dniu sobota, 19 stycznia 2019 20:13:48 UTC+1 użytkownik Lynn McGuire napisał: > implementations for one specific algorithm, mesh simplifier, henceforth > known as simplifier.cpp, and see if going all the way to C is worthwhile." > https://zeuxcg.org/2019/01/17/is-c-fast/ the outcome and conclusion of this article is obious, (doeas realy somebody didnt know that?) : c++ has some subset that is same fast as c eventually one thing interesting to see there was comparison of compile times and run times of initial c++ and final c-like c++ (compiles 3-4 times slower, runtimes 2 times slower) this may be representative (though as to compile times it much depend on compiler, as afair they not muche optimized for speed and i guess both c and simple c++ could go much faster anyway) |
Juha Nieminen <nospam@thanks.invalid>: Jan 21 02:33PM > the outcome and conclusion of this article is obious, (doeas realy > somebody didnt know that?) : c++ has some subset that is same fast as c Know your tools. Just because doing things in way X, which might eschew the convenience of eg. the standard library, results in more efficient code, that doesn't mean that *the entire program* has to be done in that way. Use the hacker optimizations where they are needed. In less critical parts, use what's best for the development and maintenance of the project. There might be some really time-critical number-crunching sections of the program where you want to engage in some really low-level optimization (such as cache optimization), but that doesn't mean that the entire million-lines-of-code program has to be done in the same way. --- news://freenews.netfront.net/ - complaints: news@netfront.net --- |
James Kuyper <jameskuyper@alumni.caltech.edu>: Jan 21 10:13AM -0500 On 1/20/19 14:22, David Brown wrote: > How about if you are absolutely certain that such code is rare, and not > your fault or your problem, and that neither you nor others reading your > code should suffer extra ugliness because of such rare code? If it's merely rare, rather than none-existent, you have to decide whether suffering the ugliness or suffering the occasional hard-to-debug error is worse. It's a judgment call, and as such, I can't fault a decision EITHER way. But it is not something that should absolutely obviously be chosen only one way. > sense to take precautions against more likely accidental mistakes, but > this is not one of them. And the :: prefix to "std" will not help if > someone puts their own code in "std" ... But such code had undefined behavior, and seems trivially diagnosable to me, so I would hope for some compiler protection against it. > ... - it would only help against > someone making a new nested namespace called "std". That, on the other hand, has perfectly well-defined behavior - behavior which might not be what you want if you ignore that possibility. At most, a compiler can issue a warning - it's not allowed to reject such code. |
David Brown <david.brown@hesbynett.no>: Jan 21 04:34PM +0100 On 21/01/2019 16:13, James Kuyper wrote: > error is worse. It's a judgment call, and as such, I can't fault a > decision EITHER way. But it is not something that should absolutely > obviously be chosen only one way. Agreed. But has anyone ever seen code for which it could help? That would prove that the problem is not non-existent. >> someone puts their own code in "std" ... > But such code had undefined behavior, and seems trivially diagnosable to > me, so I would hope for some compiler protection against it. Certainly compilers could help here. However, while putting your own code in std:: is undefined behaviour, that does not mean it is not sometimes useful. The situation is analogous to making your own definitions of standard C library functions. When done with due care and respect, for non-portable code, it can be useful. |
Richard Damon <Richard@Damon-Family.org>: Jan 21 11:03AM -0500 On 1/21/19 10:34 AM, David Brown wrote: > analogous to making your own definitions of standard C library > functions. When done with due care and respect, for non-portable code, > it can be useful. One exception to this rule is for templates defined in the ::std namespace. The programmer is allowed to add specializations for these templates, as long as at least 1 of the template parameters is a user defined type, and the definition meets the requirements for that template. (20.5.4.2.1p1) |
scott@slp53.sl.home (Scott Lurndal): Jan 21 04:42PM >I've run C bare metal. No RTL at all, and a few lines of assembler to >start it up. >Andy Actually, you can. I've run C++ bare metal (two different bare metal hypervisors and a massively parallel distributed Unix-like microkernel based operating system), no RTL and a handful of lines to support compiler generated symbols and a few lines of assembler to start it up. A page based allocator and a generic pool class suffices to support dynamic allocation (via overloaded 'new'/'delete'). Of course, no exceptions or RTTI. // // C++ Support functions // /* * Symbols defined in the linker script to mark the ctor list. */ extern void (*__CTOR_LIST__[])(); #include "dvmm.h" #include "util/support.h" /* * This is called by setup64.S to call the constructors of global objects, * before it calls dvmm_bsp_start(). * * GNU LD lays out the __CTOR_LIST__ as an array of function pointers. The * first element of the array (index == 0) contains an integer which * represents the value derived from subtracting two from the actual number * of entries in the table. Thus the content of the first element is * one less than the index of the last entry in the table. * * Call in reverse order XXX - why? Check crt0.o for canonical behavior */ extern "C" void __call_constructors() { size_t count = *(size_t *)__CTOR_LIST__; for(count++; count; --count) { __CTOR_LIST__[count](); } } /* * G++'s generated code calls this if a pure virtual member is ever called. */ extern "C" void __cxa_pure_virtual() { panic("pure virtual function called\n"); } /* * This is needed even though we don't ever use the delete operator because * G++ generates an extra (unused) virtual destructor that calls it. */ void operator delete(void *) { panic("operator delete(void*) called\n"); } /* * Catch unintended calls to new. */ void* operator new(size_t) { panic("operator new(void*) called\n"); } /* * G++ generates code for shared library support, even though it isn't * relevant (or called). That code looks for this symbol. */ void *__dso_handle; /* * Global object constructors call this to register their corresponding * destructor. We just ignore it; we never call global object destructors * because we never exit. */ extern "C" int __cxa_atexit(void (*f)(void *), void *p, void *d) { return 0; } |
fir <profesor.fir@gmail.com>: Jan 21 09:42AM -0800 W dniu poniedziałek, 21 stycznia 2019 17:42:45 UTC+1 użytkownik Scott Lurndal napisał: > { > return 0; > } interesting, as far as i remember i disasembled pure c codes from gcc and things like that also was showing in disasembly (but maybe im wrong, it seems wrong like i compiled c code in c++ mode maybe.. now it seems clearer anyway) where are the old limes whan you knew all sole byte in disasembly of your app? |
Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk>: Jan 21 06:38PM On 21/01/2019 16:42, Scott Lurndal wrote: > assembler to start it up. A page based allocator and a generic > pool class suffices to support dynamic allocation (via overloaded > 'new'/'delete'). Of course, no exceptions or RTTI. I don't see why supporting C++ exceptions in an OS kernel is too onerous, or RTTI for that matter (but one should keep dynamic_cast to minimum but that is a different story). /Flibble -- "You won't burn in hell. But be nice anyway." – Ricky Gervais "I see Atheists are fighting and killing each other again, over who doesn't believe in any God the most. Oh, no..wait.. that never happens." – Ricky Gervais "Suppose it's all true, and you walk up to the pearly gates, and are confronted by God," Bryne asked on his show The Meaning of Life. "What will Stephen Fry say to him, her, or it?" "I'd say, bone cancer in children? What's that about?" Fry replied. "How dare you? How dare you create a world to which there is such misery that is not our fault. It's not right, it's utterly, utterly evil." "Why should I respect a capricious, mean-minded, stupid God who creates a world that is so full of injustice and pain. That's what I would say." |
Christian Gollwitzer <auriocus@gmx.de>: Jan 21 07:53PM +0100 Am 21.01.19 um 19:38 schrieb Mr Flibble: > I don't see why supporting C++ exceptions in an OS kernel is too > onerous, or RTTI for that matter (but one should keep dynamic_cast to > minimum but that is a different story). How do you handle stack unwinding, especially when the exception hits the stack level where user code called into the kernel? The user code also doesn't need to explicitly call the kernel, it could also be interrupted by preemptive multitasking at any point. Christian |
Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk>: Jan 21 07:24PM On 21/01/2019 18:53, Christian Gollwitzer wrote: > stack level where user code called into the kernel? The user code also > doesn't need to explicitly call the kernel, it could also be interrupted > by preemptive multitasking at any point. I am not suggesting kernel exceptions would be exposed to userland; they would be an internal implementation detail entirely. Stack unwinding would hit a last chance try block which could panic (so stack unwinding is not exposed to userland). I admit I don't actually know what I am talking about as I have yet to create an operating system as a hobby project -- so many other things to do and life is too short and there aren't enough hours in a day. I am reinventing enough wheels as it is. /Flibble -- "You won't burn in hell. But be nice anyway." – Ricky Gervais "I see Atheists are fighting and killing each other again, over who doesn't believe in any God the most. Oh, no..wait.. that never happens." – Ricky Gervais "Suppose it's all true, and you walk up to the pearly gates, and are confronted by God," Bryne asked on his show The Meaning of Life. "What will Stephen Fry say to him, her, or it?" "I'd say, bone cancer in children? What's that about?" Fry replied. "How dare you? How dare you create a world to which there is such misery that is not our fault. It's not right, it's utterly, utterly evil." "Why should I respect a capricious, mean-minded, stupid God who creates a world that is so full of injustice and pain. That's what I would say." |
Daniel <danielaparker@gmail.com>: Jan 21 06:30AM -0800 On Monday, January 21, 2019 at 1:26:03 AM UTC-5, Paavo Helde wrote: > > }; > Iterator is over something like std::map or std::vector, not over > std::pair, Over the elements in an associative map of type std::pair<const T1,T2>, or over the elements in a container of any sort where they come as std::pair<T1,T2> or std::pair<const T1,T2>. I'm sorry if that wasn't obvious. > > reference operator*() { return key_value(it->first,it->second); } > As written, this is not an iterator as it is lacking an increment > operation (would be easy to add though). I'm sorry if it wasn't obvious that I'm highlighting the typedef of the reference in the context of a LegacyInputIterator. My apologies. > Also, the 'reference' type is not a reference, misleading the user. I'm sure you're aware that boost many times uses #typedef value_type reference; in other contexts for technical reasons. And misleading in what sense? There are actually a fair number of places in boost where X::reference does not equate to &X::value_type, for technical reasons. For what reason would a user expect that? A user is right to expect member types to have properties that satisfy the requirements of the language, but no more. My question was about whether the line (*) above violated any formal properties of a LegacyInputIterator. > This also means that this adaptor can only be used as InputIterator, I included the LegacyInputIterator tag in my fragment to frame that as the context. > inside an iterator? > I would iterate over the collection normally and > just convert the elements inside the loop as needed. Taken literally, I don't think that makes sense, as a user wouldn't have access to the implementation details of a class in another library that takes a pair of iterators over key_value<T1,T2>'s in a constructor, or an insert statement. Typically that's the context when you require an adapter, when you have one thing, and need another. I apologize if that wasn't obvious. Perhaps you're suggesting that the class in the other library should support, say, template<class InputIt, class Convert> void insert(InputIt first, InputIt last, Convert convert) { and allow, perhaps j.insert(items.begin(), items.end(), [](const std::pair<const T1,T2>& p){return key_value<T1,T2>(p.first,p.second);}); Thanks, Daniel |
Paavo Helde <myfirstname@osa.pri.ee>: Jan 21 06:41PM +0200 On 21.01.2019 16:30, Daniel wrote: > I included the LegacyInputIterator tag in my fragment to frame that as the > context. Sorry, it seems I overlooked that. Now it makes much more sense. > in a constructor, or an insert statement. Typically that's the context > when you require an adapter, when you have one thing, and need another. > I apologize if that wasn't obvious. If the other library cannot be modified, then your solution is indeed the way to go. However, the needed modifications are minor and make the other library more generic, see below. > j.insert(items.begin(), items.end(), > [](const std::pair<const T1,T2>& p){return > key_value<T1,T2>(p.first,p.second);}); This now means that the first library must know about the internal details of the other library like key_value. IMHO a better design is to define insert() in the other library such a way that it works with more generic iterator types and converts the data itself into its internal key_value or whatever: template <class T1, class T2> struct key_value { T1 key; T2 value; key_value(const std::pair<T1, T2>& init) : key(init.first), value(init.second) {} }; template <class T1, class T2> void foo(const key_value<T1, T2>& x) { // do something with key_value } template<class InputIt> void insert(InputIt first, InputIt last) { while (first!=last) { foo(key_value(*first++)); } } This now supports iterators to key_value as well as to all types convertible to key_value. (note: as written, the above requires C++17 for class template argument deduction). |
Daniel <danielaparker@gmail.com>: Jan 21 10:17AM -0800 On Monday, January 21, 2019 at 11:41:14 AM UTC-5, Paavo Helde wrote: > convertible to key_value. > (note: as written, the above requires C++17 for class template argument > deduction). Thanks, that's helpful feedback. Daniel |
scott@slp53.sl.home (Scott Lurndal): Jan 21 04:45PM >I read this as "elapsedTimeInDays is bad, daysSinceCreation or >daysSinceModification or fileAgeInDays would be better". >(S)He could have made this more clear, though. struct stat's st_atime, st_ctime, st_mtime seem clear enough to me... |
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