Friday, August 14, 2020

Digest for comp.lang.c++@googlegroups.com - 23 updates in 3 topics

Nikki Locke <nikki@trumphurst.com>: Aug 14 10:23PM

Available C++ Libraries FAQ
 
URL: http://www.trumphurst.com/cpplibs/
 
This is a searchable list of libraries and utilities (both free
and commercial) available to C++ programmers.
 
If you know of a library which is not in the list, why not fill
in the form at http://www.trumphurst.com/cpplibs/cppsub.php
 
Maintainer: Nikki Locke - if you wish to contact me, please use the form on the website.
RM <robert_magdziarz@wp.pl>: Aug 14 02:16PM +0200

I am learning C++.
I have the code:
 
class strvector : public std::vector<std::string> {
...
};
 
class obfuscator {
...
strvector (*identifiers)[INDEX_WHAT_NUM],
(*random_identifiers)[INDEX_WHAT_NUM],
(*framework_identifiers)[INDEX_WHAT_NUM];
...
obfuscator() {
...
identifiers = new strvector[INDEX_WHAT_NUM];
random_identifiers = new strvector[INDEX_WHAT_NUM];
framework_identifiers = new strvector[INDEX_WHAT_NUM];
...
}
~obfuscator() {
delete [] identifiers;
delete [] random_identifiers;
delete [] framework_identifiers;
}
...
};
 
And I have errors:
 
src/obfuscator.hpp: In constructor 'obfuscator::obfuscator()':
src/obfuscator.hpp:75:51: error: incompatible types in assignment of
'strvector*' to 'strvector [5]'
identifiers = new strvector[INDEX_WHAT_NUM];
^
src/obfuscator.hpp:76:58: error: incompatible types in assignment of
'strvector*' to 'strvector [5]'
random_identifiers = new strvector[INDEX_WHAT_NUM];
^
src/obfuscator.hpp:77:61: error: incompatible types in assignment of
'strvector*' to 'strvector [5]'
framework_identifiers = new strvector[INDEX_WHAT_NUM];
 
How to correct my code?
Sam <sam@email-scan.com>: Aug 14 08:43AM -0400

RM writes:
 
> ...
> strvector (*identifiers)[INDEX_WHAT_NUM], (*random_identifiers)
> [INDEX_WHAT_NUM], (*framework_identifiers)[INDEX_WHAT_NUM];
 
identifiers is an array. It pops into existence all of its own. Ditto for
the others.
 
> identifiers = new strvector[INDEX_WHAT_NUM];
> random_identifiers = new strvector[INDEX_WHAT_NUM];
> framework_identifiers = new strvector[INDEX_WHAT_NUM];
 
These class members already exist. They don't need to be `new`ed or deleted.
 
Now, you do need to `new` each one of these INDEX_WHAT_NUM strvectors,
individually, one by one.
 
> delete [] random_identifiers;
> delete [] framework_identifiers;
> }
 
And then delete each one, one by one in the destructor.
 
But really, let me let you in on a very closely held secret. Promise not to
tell anyone, this secret that's known only by a handful of C++ gurus in the
world:
 
In modern C++, there is rarely a need to new or delete anything. Rather, you
use containers do all that work for you. Or, in case of fixed-size arrays,
just declare them:
 
strvector identifiers[INDEX_WHAT_NUM], random_identifiers[INDEX_WHAT_NUM],
framework_identifiers[INDEX_WHAT_NUM];
 
 
Its unclear whether strvector has a default constructor or not. Just
declaring a plain array requires a default constructor. Otherwise, simply
use std::vector, with a smart use of `reserve()` to avoid needless copying,
and let std::vector do all the work of new-ing and delete-ing, all by itself.
 
Its, of course, important to understand how dynamic memory allocations work.
But it is rarely needed in most simple use cases.
 
> How to correct my code?
 
Get rid of new and delete, complete. Use vectors, or lists, or some other
container that will do this for you.
Bonita Montero <Bonita.Montero@gmail.com>: Aug 14 02:57PM +0200

Although there might be workarounds the issue of the OP is still
interesting.
RM <robert_magdziarz@wp.pl>: Aug 14 03:03PM +0200

W dniu 14.08.2020 o 14:43, Sam pisze:
>> How to correct my code?
 
> Get rid of new and delete, complete. Use vectors, or lists, or some
> other container that will do this for you.
 
I tried heap allocation because I had core dumped when I used stack
allocation (local variables). I don't know why because I use little memeory.
RM <robert_magdziarz@wp.pl>: Aug 14 03:46PM +0200

> I tried heap allocation because I had core dumped when I used stack
> allocation (local variables). I don't know why because I use little
> memeory.
 
I use g++ in Linux Mint.
RM <robert_magdziarz@wp.pl>: Aug 14 03:55PM +0200

W dniu 14.08.2020 o 15:46, RM pisze:
>> allocation (local variables). I don't know why because I use little
>> memeory.
 
> I use g++ in Linux Mint.
 
To be precise I have core dumped and I have in gdb:
 
#0 __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:51
51 ../sysdeps/unix/sysv/linux/raise.c: Nie ma takiego pliku ani katalogu.
(gdb) bt
#0 __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:51
#1 0x00007f98bd7d5801 in __GI_abort () at abort.c:79
#2 0x00007f98bde2a957 in ?? () from
/usr/lib/x86_64-linux-gnu/libstdc++.so.6
#3 0x00007f98bde30ae6 in ?? () from
/usr/lib/x86_64-linux-gnu/libstdc++.so.6
#4 0x00007f98bde30b21 in std::terminate() ()
from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#5 0x00007f98bde30d54 in __cxa_throw ()
from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#6 0x00007f98bde312dc in operator new(unsigned long) ()
from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#7 0x00007f98bdec2b8b in std::__cxx11::basic_string<char,
std::char_traits<char>, std::allocator<char> >::_M_mutate(unsigned long,
unsigned long, char const*, unsigned long) () from
/usr/lib/x86_64-linux-gnu/libstdc++.so.6
#8 0x00007f98bdec4133 in std::__cxx11::basic_string<char,
std::char_traits<char>, std::allocator<char> >::_M_append(char const*,
unsigned long) ()
from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#9 0x00000000004098d1 in std::operator+<char, std::char_traits<char>,
std::allocator<char> > (__lhs=..., __rhs="")
at /usr/include/c++/7/bits/basic_string.h:5955
#10 0x000000000040838e in obfuscator::obfuscator (this=0x7ffd4feca0e0)
at src/obfuscator.hpp:69
#11 0x000000000040781b in main (argc=6, argv=0x7ffd4feca678)
at src/dirtyphp.cpp:37
RM <robert_magdziarz@wp.pl>: Aug 14 04:16PM +0200

W dniu 14.08.2020 o 15:55, RM pisze:
>     at src/obfuscator.hpp:69
> #11 0x000000000040781b in main (argc=6, argv=0x7ffd4feca678)
>     at src/dirtyphp.cpp:37
 
After reinstalling g++ I have:
 
#0 __memmove_avx_unaligned_erms ()
at ../sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S:371
371 ../sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S: Nie ma
takiego pliku ani katalogu.
(gdb) bt
#0 __memmove_avx_unaligned_erms ()
at ../sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S:371
#1 0x00007fa7a3e55bda in std::__cxx11::basic_string<char,
std::char_traits<char>, std::allocator<char> >::_M_mutate(unsigned long,
unsigned long, char const*, unsigned long) () from
/usr/lib/x86_64-linux-gnu/libstdc++.so.6
#2 0x00007fa7a3e57133 in std::__cxx11::basic_string<char,
std::char_traits<char>, std::allocator<char> >::_M_append(char const*,
unsigned long) ()
from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#3 0x00000000004098d1 in std::operator+<char, std::char_traits<char>,
std::allocator<char> > (__lhs=...,

__rhs="\020(\v\244\247\177\000\000\002\000\000\000\000\000\000\000H\374\n\244\247\177\000\000\002\000\000\000\000\000\000\000\000t\v\244\247\177\000\000\000\000\000\000\000\000\000\000\330\373\n\244\247\177\000\000\002\000\000\000\000\000\000\000`)\261\243\247\177",
'\000' <repeats 26 times>,
"\020\330\n\244\247\177\000\000\002\000\000\000\000\000\000\000`)\261\243\247\177\000\000\001\000\001\002\003\004\005\006\a\b\t\n\v\f\r\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037
!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMN"...)
at /usr/include/c++/7/bits/basic_string.h:5955
#4 0x000000000040838e in obfuscator::obfuscator (this=0x7ffe10828cb0)
at src/obfuscator.hpp:69
#5 0x000000000040781b in main (argc=6, argv=0x7ffe10829248)
at src/dirtyphp.cpp:37
Barry Schwarz <schwarzb@delq.com>: Aug 14 07:47AM -0700

>src/obfuscator.hpp:75:51: error: incompatible types in assignment of
>'strvector*' to 'strvector [5]'
> identifiers = new strvector[INDEX_WHAT_NUM];
 
This error message is inconsistent with the above code. identifiers
does not have type strvector[5]. It has type strvector(*)[5] which is
completely different.
 
The easiest way for us to help you would be for you to provide a
small, complete, compilable program that produces the error in
question. When you post the program in a message, use cut and paste
rather than retype it. Retyping often introduces mistakes that don't
appear in the original.
 
In a subsequent message you stated you had problems using arrays that
were declared explicitly. Show us that code also so we can see what
you are doing wrong.
 
Based on both messages, I think you have a fundamental
misunderstanding about arrays but we will probably be able to correct
that also when you show us the code.
 
--
Remove del for email
Bo Persson <bo@bo-persson.se>: Aug 14 06:32PM +0200

On 2020-08-14 at 14:16, RM wrote:
> 'strvector*' to 'strvector [5]'
>          framework_identifiers = new strvector[INDEX_WHAT_NUM];
 
> How to correct my code?
 
You have to consider if you want an array of pointers,
 
strvector (*identifiers)[INDEX_WHAT_NUM]
 
or a pointer to an array
 
new strvector[INDEX_WHAT_NUM]
 
Those are not the same thing.
 
 
BTW, a std::vector doesn't store the data elements on the stack, but
uses heap allocation internally (and likely does that correctly :-)). If
you run out of stack space, you have some other problem.
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Aug 14 07:06PM +0200

On 14.08.2020 14:16, RM wrote:
> [snip]
>     strvector (*identifiers)[INDEX_WHAT_NUM],
 
This is a pointer to a complete array of `strvector`, because
 
`*identifiers` gives you what identifiers points to, and
THAT[n] gives you the beyond-the-last item.
 
Instead of using the old C syntax you could write
 
std::array<strvector, INDEX_WHAT_NUM>* identifiers;
 
Or instead of using the standard library type you could define
 
template< class T > using Type_ = T;
 
and then write
 
Type_<strvector[INDEX_WHAT_NUM]>* identifiers;
 
The question is whether that's what you really wanted, because
 
 
> [snip]
>         identifiers = new strvector[INDEX_WHAT_NUM];
 
... produces a `strvector*, i.e. a pointer to the first item in the
allocated array, and not a pointer to the complete array as such.
 
The difference is just one of type, not of memory address.
 
But it's enough to make the compiler say no.
 
 
[snip]
> How to correct my code?
 
It depends what you want.
 
If you just want a dynamic size array of strings, then
 
vector<string> m_identifiers;
 
But if you want a dynamic size array of dynamic size arrays of strings, then
 
vector<vector<string>> m_identifiers;
 
That's closest to the presented code but I believe you really want the
first one.
 
 
- Alf
Juha Nieminen <nospam@thanks.invalid>: Aug 14 05:26PM

> strvector (*identifiers)[INDEX_WHAT_NUM],
> (*random_identifiers)[INDEX_WHAT_NUM],
> (*framework_identifiers)[INDEX_WHAT_NUM];
 
The answers to this question go to show that even many experienced C++
programmers don't know their pointer syntax.
 
Type (*name)[size]
 
is a pointer to a Type[size], ie. an array of size elements of type Type.
 
This is *not* the same thing as a pointer-to-Type. This is a
pointer-to-Type[size], which is different.
 
For instance, if you increment a Type*, it will advance by sizeof(Type) bytes,
but if you increment a Type(*)[size], it will advance by sizeof(Type)*size
bytes.
 
Most often Type(*name)[size] is used as a pointer to a 2-dimensional array,
where the second dimension is 'size'. In other words:
 
Type table[12][34];
Type (*ptr)[34] = table;
 
Here you see that if you do a ++ptr, it will advance to the next row in
the array, ie. it will advance by an entire row, ie by sizeof(Type)*34
bytes.
 
Your code does not look like you want a pointer to a 2-dimensional array.
It looks to me that you simply wanted:
 
strvector *identifiers, *random_identifiers, *framework_identifiers;
 
These are pointers-to-strvector, which also double as "pointer to an array
of strvector objects" (an ambiguity inherited from C).
 
That being said, it's usually recommended against using raw pointers and
'new'. Just use members of strvector directly:
 
strvector identifiers, random_identifiers, framework_identifiers;
 
Since strvector is just an std::vector, there's really no reason not to.
Barry Schwarz <schwarzb@delq.com>: Aug 14 11:16AM -0700

On Fri, 14 Aug 2020 18:32:02 +0200, Bo Persson <bo@bo-persson.se>
wrote:
 
>You have to consider if you want an array of pointers,
 
>strvector (*identifiers)[INDEX_WHAT_NUM]
 
That is not an array of pointers. It is a pointer to an (entire)
array. An array of pointers would be declared as
strvector *array[5]
 
--
Remove del for email
Sam <sam@email-scan.com>: Aug 14 05:51PM -0400

RM writes:
 
>> container that will do this for you.
 
> I tried heap allocation because I had core dumped when I used stack
> allocation (local variables). I don't know why because I use little memeory.
 
If you do not understand the reason why your program crashes, trying
different things at random will rarely fix anything. Especially other things
that you don't even fully understand the inner workings of.
 
You need to investigate the reason for your crashes, and fix them.
 
Unfortunately, posting your backtraces to the Intertubes does not convey
anything meaningful. Backtraces are utterly useless to anyone except the one
who produced the backtrace. Backtraces aren't, by themselves a "here's where
the bug is" solution. All that a backtrace tells you is the sequence of
function calls that led to the crash. How does that tell you what the bug
is? Very rarely it does, but almost never.
 
Backtraces are only a starting point. Unfortunately there is no paint-by-
numbers, cookie-cutter recipe for figuring out the bug, from a backtrace.
Each crash is unique, and distinct in its nature. Typically one would see,
from the backtrace, where your written code ends, and system libraries start
(if any), then go up to call stack back to where your code made the library
call, then investigate the state of the program and the data, at the time of
the library call. Inspect all variables, pointers, determine what the
problem with the state of the program is. Maybe even back up a few more
stack frames, if it's clear that something went sideways further up the call
chain. Or, you may discover such a dumpster fire already in progress that
the only thing that you can do is set a breakpoint earlier in the code, at
some meaningful place, before execution reaches here, run the program again,
and see how things shape up at an earlier point in the execution.
Juha Nieminen <nospam@thanks.invalid>: Aug 14 12:14AM

> when you don't realize you have *this* problem.
 
> If you don't have use for co-routines this does not mean nobody does.
> For example, I have not found use for std::list and I'm not complaining.
 
It took me some time to understand what coroutines are good for, but
once I figured out this practical example, I think it' makes it quite
clear. (I have mentioned this in the past, but I suppose it doesn't
hurt repeating.)
 
Suppose you are decompressing a file (or compressed data that's
coming in or whatever). You have a fixed-sized array into which
you are storing the decompressed data. The idea is that once the
array gets full, you should call some "consumer" code that handles
the uncompressed data (and thus "empties" the array of it), after
which you continue decompressing more data into it.
 
The thing is, compressed data tends to be in some kind of chunks,
ie. when you decompress one "unit" if compressed data, the resulting
decompressed data may not fit neatly in the array, filling it
completely (or fitting inside it in the first place, even if the
array was empty). You would need to partially decompress this
chunk of compressed data and fill the array with the decompressed
data, call the "consumer" code, and then continue decompressing
from where you left (now filling the array from the beginning).
 
In other words, you need to be able to stop decompressing somewhere
in the middle of your decompression routine, call the outside code,
and then resume from where you left.
 
Normally this means that you need to store the entire state of your
decompressor somewhere, and then code the logic that allows you to
continue from where you left off. This becomes quite complicated
if there are many points in the decompressor code where the output
array may get full and thus it needs to stop, call the "consumer",
and then continue.
 
This is where coroutines step in to largely automatize this entire
process. At any point in your decompressor, if the output array may
get full, you simply "yield", and then continue as normal. You don't
need to keep the entire decompressor state stored somewhere, you don't
need to remember which "yield" point you were last in, you don't need
to code any logic to jump back to that particular "yield" point.
Coroutines take care of all that automatically for you.
 
It is, of course, perfectly possible to do all this without
coroutines, but it's much more laborious. Coroutines automatize
most of this.
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Aug 14 06:52AM +0200

On 14.08.2020 02:14, Juha Nieminen wrote:
 
> It is, of course, perfectly possible to do all this without
> coroutines, but it's much more laborious. Coroutines automatize
> most of this.
 
It used to be called a Jackson (data) "structure clash" problem. Not
after Michael Jackson, but after the Jackson who invented manually
structured Cobol programming. I remember that some years ago it was
already very difficult to convince Mr. Google to find anything about it,
but at one time just about every corporate developer knew about it.
 
- Alf
Jorgen Grahn <grahn+nntp@snipabacken.se>: Aug 14 07:10AM

On Thu, 2020-08-13, Brian Wood wrote:
 
> Years ago Gcc and Clang were making some progress on
> static exceptions. I'm wondering if that work has been
> totally derailed now by 2020 C++.
 
I don't know anything about the feature, but it's normal for a new
language feature to get prototyped in either of those compilers. Then
people play with it, and if enough like it, it ends up in the
language.
 
Compiler-specific extensions haven't been popular in recent decades,
so if it turns out the feature won't be standardized, it probably
won't make it to a real g++ or clang release.
 
/Jorgen
 
--
// Jorgen Grahn <grahn@ Oo o. . .
\X/ snipabacken.se> O o .
Sam <sam@email-scan.com>: Aug 14 07:11AM -0400

Paavo Helde writes:
 
>> problem.
 
> More like a solution which you need to poorly reinvent or work around when
> you don't realize you have *this* problem.
 
I have no idea where I would be without someone telling me that I have some
problem I don't know about.
 
Probably sitting in a dark room, pulling my hair out, or something, living
in perpetual fear of all these hidden problem boogeymen.
Sam <sam@email-scan.com>: Aug 14 07:15AM -0400

Juha Nieminen writes:
 
> clear. (I have mentioned this in the past, but I suppose it doesn't
> hurt repeating.)
 
> Suppose you are decompressing a file (or compressed data that's
 
Or, instead of doing all of this, implement a push-based API.
 
> It is, of course, perfectly possible to do all this without
> coroutines, but it's much more laborious. Coroutines automatize
> most of this.
 
Gee, that's neat. Almost as neat as throw specifications. Oh, wait…
Juha Nieminen <nospam@thanks.invalid>: Aug 14 05:14PM

>> coroutines, but it's much more laborious. Coroutines automatize
>> most of this.
 
> Gee, that's neat. Almost as neat as throw specifications. Oh, wait???
 
Sounds more like the stubborn people who complain about all changes will
refuse to use it, while people who understand the use of the feature
will save themselves a lot of trouble by just using it.
 
It's like those C hackers who always complain how templates are too
complicated and how they love to make everything by hand in C, while
experienced C++ programmers will just use templates without much
problems and get things done much easier and faster (and often
even producing a more efficient result).
red floyd <no.spam.here@its.invalid>: Aug 14 01:36PM -0700

On 8/14/2020 4:11 AM, Sam wrote:
 
 
> some problem I don't know about.
 
> Probably sitting in a dark room, pulling my hair out, or something,
> living in perpetual fear of all these hidden problem boogeymen.
 
So if you don't have a need for the feature, don't use it. Just because
it doesn't fit YOUR use case, doesn't mean that others don't like it.
 
Chill out, dude.
Sam <sam@email-scan.com>: Aug 14 05:50PM -0400

Juha Nieminen writes:
 
 
> Sounds more like the stubborn people who complain about all changes will
> refuse to use it, while people who understand the use of the feature
> will save themselves a lot of trouble by just using it.
 
I wonder how many people decided that throw specifications were the greatest
thing since sliced bread, and started sprinkling them all over the place, as
a prophylactic measure, to catch bugs earlier? Where are they now?
 
Or, everyone who thought that std::vector<bool> was brilliant. Very useful,
right?
Sam <sam@email-scan.com>: Aug 14 05:50PM -0400

red floyd writes:
 
> > living in perpetual fear of all these hidden problem boogeymen.
 
> So if you don't have a need for the feature, don't use it. Just because
> it doesn't fit YOUR use case, doesn't mean that others don't like it.
 
Where did I claim that nobody liked it? I never said that. The only thing
that I said is that it's something I would've come up with myself, after
injesting a few mushrooms.
 
I'm sure that someone, some time ago, really liked `std::vector<bool>`, and
thought that it was the greatest invention that humankind ever made.
 
I'm sure that there will be those that, for whatever reasons, like co-
routines, and start cranking them out like they're going out of style. Bless
their little hearts.
 
I really don't understand why someone would get so disjointed in response to
my disparaging remarks. I'm humbled at the thought that someone values my
opinions so much that they get enturbulated when I dis their favorite toys.
 
If someone started bad-mouthing, for example, real execution threads –
which is something that I'm very found of – I don't think I'd care. I'd
read the rant, smirk, and move on. Why would I care about some other rando's
stream of consciousness? Who are they to me? Nobody. Why should I care?
Can't think of a reason.
 
> Chill out, dude.
 
I'm perfectly chilled.
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: