Monday, January 21, 2019

Digest for comp.lang.c++@googlegroups.com - 19 updates in 6 topics

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: