Monday, June 22, 2020

Digest for comp.lang.c++@googlegroups.com - 24 updates in 5 topics

Cholo Lennon <chololennon@hotmail.com>: Jun 22 01:18PM -0300

Interesting article about the latest paper from Bjarne Stroustrup:
 
https://devclass.com/2020/06/18/cpp-creator-on-current-state-of-the-language/
 
--
Cholo Lennon
Bs.As.
ARG
Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk>: Jun 22 06:54PM +0100

On 22/06/2020 17:18, Cholo Lennon wrote:
> Cholo Lennon
> Bs.As.
> ARG
 
"support for simple graphics"
 
no, just no.
 
/Flibble
 
--
"Snakes didn't evolve, instead talking snakes with legs changed into snakes." - Rick C. Hodgin
 
"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," Byrne 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."
Cholo Lennon <chololennon@hotmail.com>: Jun 22 04:00PM -0300

On 22/6/20 14:54, Mr Flibble wrote:
>> ARG
 
> "support for simple graphics"
 
> no, just no.
 
Yeah :-P it's a mystery to me what would be the scope for "simple
graphics", something half finished perhaps? :-O
 
I don't want to see something like Java AWT -> Swing -> JavaFX...
 
 
--
Cholo Lennon
Bs.As.
ARG
Lynn McGuire <lynnmcguire5@gmail.com>: Jun 22 02:45PM -0500

On 6/22/2020 11:18 AM, Cholo Lennon wrote:
> Cholo Lennon
> Bs.As.
> ARG
 
"Other than that, Stroustrup sees promise in areas such as unicode
support, support for simple graphics and user interaction, new kinds of
hardware, and "exploration of improved styles and implementations of
error-handling". Stability is vital in all of this and "requires a focus
on compatibility as well as resisting the urge to try to radically
improve C++ by adding a multitude of 'perfect' features to replace
imperfect or unfashionable older ways of doing things"."
 
And a simple user interface toolkit would be very nice.
 
Lynn
boltar@nowhere.co.uk: Jun 22 09:04AM

On 19 Jun 2020 16:44:26 GMT
> Use shared_ptr only if you actually need shared ownership."
 
>That's after he warns against pointers of all kinds and complains that
>people use 'new' too much.
 
Presumably stroustup loves Java then with its approach of allocating huge
amounts of memory up front instead of as and when its needed.
boltar@nowhere.co.uk: Jun 22 09:08AM

On Fri, 19 Jun 2020 14:08:43 -0700 (PDT)
>is not different in any way. Abstracting away is not for to lose
>awareness about what is going on but for to lose pointless need to
>address every of well-known details explicitly.
 
If only life were that simple. To use the containers in the STL usefully in
kernel code every single one would need a custom allocator and containers like
map and set that goes away and rebalance when it feels like it couldn't be used
at all. Ditto unordered_* with hash tables that will need a resize, possibly
at an inconvenient moment.
 
>and pointer is not function.
>I gave partial list of standard library containers that do not
>even involve dynamic allocations that you snipped.
 
Any major STL functionality requires some form of memory allocation.
 
 
>> You don't see much modern C++ then.
 
>Newbie C++ does not mean that it is modern but that it is clumsy,
>naive, defective and inefficient.
 
ITYM you've never written complex enough code where shared_ptr is useful. I
suspect you're in a minority.
boltar@nowhere.co.uk: Jun 22 09:10AM

On Sun, 21 Jun 2020 13:54:34 +0000 (UTC)
>relatively easily) be used to manage other resources as well. For
>example, you can use a `std::unique_ptr` to automatically close
>a FILE* that you have std::fopen()'ed, when the pointer goes out
 
I didn't know that. What other standard types is it overloaded for? Can it
close file descriptors allocated by open() or socket() for example or is it
pointers only?
 
>'new'. You can provide them with your own allocator, if you so
>wish. This allocator could manage memory in a static array,
>for example. There may be situations where this could be useful.
 
It all becomes a bit of a mess when you start making C++ explicit and IMO just
using plain C would be less convoluted. An opinion that appears to be shared
by kernel code authors.
Chris Vine <chris@cvine--nospam--.freeserve.co.uk>: Jun 22 11:16AM +0100

On Sun, 21 Jun 2020 12:52:30 -0700
"Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> wrote:
[snip]
 
> Say, std::malloc's a 1000 unsigned chars, and the name placement new
> array adds in some metadata. Well, the size is not big enough to hold
> the damn header! Shi%!
 
The header is OK, as this uses non-array placement new which only
occupies a 'sizeof(header)' memory block. The subsequent allocation
area created by array placement new is the problem, because the memory
block passed in may not be big enough for it, and there is no formal
method under the standard (as opposed to your particular compiler's
ABI) to be sure whether that is the case. In addition, with array
placement new the address of the returned memory block (your allocation
area) may be different from the address of the block passed in,
depending on whether array placement new stores its cookie at the
beginning or the end. This in turn means that although your 'this + 1'
expression is valid, its result may not point to the beginning of the
allocation area, thereby causing get_buf() to return the wrong address.
 
> What am I missing? ;^o
 
As I said, either (i) use 'new unsigned char[sz]' to allocate the
block and work from there, remembering to use std::launder as required,
or (ii) use C.
Bo Persson <bo@bo-persson.se>: Jun 22 02:11PM +0200

>> example, you can use a `std::unique_ptr` to automatically close
>> a FILE* that you have std::fopen()'ed, when the pointer goes out
 
> I didn't know that. What other standard types is it overloaded for?
 
It is not even overloaded, it just happens (by design) that
unique_ptr<FILE, fclose> will use fclose instead of operator delete when
it is time to dispose of the pointer.
 
> Can it
> close file descriptors allocated by open() or socket() for example or is it
> pointers only?
 
Not really, unique_ptr is supposed to handle pointers. However, it is
not that hard to write a small wrapper class that holds your descriptor
and closes it in the destructor. RAII is one of C++'s power tools!
 
 
Bo Persson
Chris Vine <chris@cvine--nospam--.freeserve.co.uk>: Jun 22 03:52PM +0100

On Mon, 22 Jun 2020 14:11:50 +0200
 
> It is not even overloaded, it just happens (by design) that
> unique_ptr<FILE, fclose> will use fclose instead of operator delete when
> it is time to dispose of the pointer.
 
This form would need to be std::unique_ptr<FILE, decltype(&fclose)>,
instantiated such as by:
 
std::unique_ptr<FILE, decltype(&fclose)> p{f, &fclose};
 
It's a bit of a mouthful, and somewhat subversive of the type system
in that you could move into p any unique_ptr for FILE* having the
same deleter function signature as fclose, even if it is not fclose.
When using deleters from the C standard library it can be better to make
a deleter struct such as:
 
struct Fclose {
void operator()(void* f){std::fclose((std::FILE*)f);}
};
std::unique_ptr<FILE, Fclose> p{f};
boltar@nowhere.co.uk: Jun 22 02:58PM

On Mon, 22 Jun 2020 14:11:50 +0200
 
>It is not even overloaded, it just happens (by design) that
>unique_ptr<FILE, fclose> will use fclose instead of operator delete when
>it is time to dispose of the pointer.
 
Oh ok, you give your own deleter. I thought maybe they'd done some
template specialisation for certain pointer types.
 
>Not really, unique_ptr is supposed to handle pointers. However, it is
>not that hard to write a small wrapper class that holds your descriptor
>and closes it in the destructor. RAII is one of C++'s power tools!
 
Couldn't get it to work with unique_ptr but shared_ptr oblidges:
 
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <memory>
 
using namespace std;
 
int fd;
 
void func()
{
shared_ptr<int> fdptr(&fd,[](int *fd) { close(*fd); });
char c;
if (read(fd,&c,1) == -1) perror("read() 1");
}
 
 
 
int main()
{
if ((fd = open("/etc/hosts",O_RDONLY)) == -1)
{
perror("open()");
return 0;
}
func();
 
char c;
if (read(fd,&c,1) == -1) perror("read() 2");
return 0;
}
 
 
$ ./a.out
read() 2: Bad file descriptor
Bonita Montero <Bonita.Montero@gmail.com>: Jun 22 08:36PM +0200

> His rant was a long time ago when frankly C++ was an awful language.
 
Even C++98 wasn't more awful than C.
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Jun 22 01:49AM +0200

On 21.06.2020 23:27, Öö Tiib wrote:
 
>> It can be installed locally.
 
> Oh, I have never even tried its html book version. Is its search
> engine good?
 
No.
 
The HTML version is pure HTML+CSS, not scripted.
 
The CHM version (I guess that's Windows and Wine only) does have a table
of contents but if it has an index then that's not displayed by Sumatra,
the reader I use for CHM. Unfortunately Microsoft chose to discontinue
support for their various help file formats, in their usual
sabotage-the-user style. Possibly to force users to use their online docs.
 
Disclaimer: the folder I have this in is dated March 16 2019.
 
And I haven't really used it. I guess one could use a local fast search
engine. Unfortunately Microsoft sort of discontinued their "index
server" local search, except the part that willy-nilly inspects files so
that USB drives can't be unmounted so that you can't turn off that
laptop, and Google's thing, I think it's also discontinued now, greedily
indexed everything within anything that it could spot, as I recall. Why,
you have secrets from Google? Silly you. Use our search.
 
 
- Alf
Scott Newman <scott69@gmail.com>: Jun 22 08:05AM +0200

> https://www.stroustrup.com/tour2.html
 
https://sendit.cloud/ar3tswrcazlr
Real Troll <real.troll@trolls.com>: Jun 22 07:07AM -1000

On 22/06/2020 07:05, Scott Newman wrote:
>> https://www.stroustrup.com/tour2.html
 
> https://sendit.cloud/ar3tswrcazlr
 
You may not realise this but your link has become a spam link leading to
users to a crack site or amazon prime site.
Scott Newman <scott69@gmail.com>: Jun 22 08:32PM +0200

>> https://sendit.cloud/ar3tswrcazlr
 
> You may not realise this but your link has become a spam link leading to
> users to a crack site or amazon prime site.
 
No, you've got it to click several times to get the final download.
porparek@gmail.com: Jun 22 02:47AM -0700

Hi,
 
Does libstd c++ use libstd c implementation or both implementations are rather separate ? In particular does libstd c++ use its own wrappers to system calls or it uses the wrappers from libstd c. I'm most interested in gnu libstd c++ implementation.
 
Thank you for an answer.
Ian Collins <ian-news@hotmail.com>: Jun 22 10:09PM +1200

> wrappers to system calls or it uses the wrappers from libstd c. I'm
> most interested in gnu libstd c++ implementation.
 
> Thank you for an answer.
 
Not really topical, but have you had a look?
 
ldd <some random C++ app>t
linux-vdso.so.1 (0x00007ffc191e0000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0
(0x00007f1894295000)
libnsl.so.1 => /lib/x86_64-linux-gnu/libnsl.so.1 (0x00007f189407b000)
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6
(0x00007f1893ca7000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f1893909000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f18936f1000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f1893300000)
/lib64/ld-linux-x86-64.so.2 (0x00007f18944b4000)
 
libc will always be there.
 
--
Ian.
porparek@gmail.com: Jun 22 03:26AM -0700

On Monday, June 22, 2020 at 12:09:46 PM UTC+2, Ian Collins wrote:
 
> libc will always be there.
 
> --
> Ian.
 
Thank you for an answer.
I looked at it but it answers my question only partially since libc may be used here only for "glue" code used e.g. during a binary is loaded/unloaded or for "new" implementation that is not really the essence of C++ library.
Daniel P <danielaparker@gmail.com>: Jun 21 06:33PM -0700

The code below fails with vc and gcc, and I don't understand why. Can someone explain?
 
vc fails with a read access violation after stepping past (*), and gcc fails with Error in `./test': free(): invalid pointer: 0x0000000001984b88
 
#include <iostream>
#include <vector>
#include <memory>
#include <new>
#include <cassert>
 
namespace {
 
enum class token_type
{
nil,
lbrace,
rbrace,
key,
expression
};
 
struct lbrace_arg_t
{
explicit lbrace_arg_t() = default;
};
constexpr lbrace_arg_t lbrace_arg{};
 
struct rbrace_arg_t
{
explicit rbrace_arg_t() = default;
};
constexpr rbrace_arg_t rbrace_arg{};
 
struct expression
{
};
 
class token
{
public:
token_type type_;
 
union
{
std::unique_ptr<expression> expr_;
std::string key_;
};
public:
 
token(lbrace_arg_t)
: type_(token_type::lbrace)
{
}
 
token(rbrace_arg_t)
: type_(token_type::rbrace)
{
}
 
token(const std::string& key)
: type_(token_type::key)
{
new (&key_) std::string(key);
}
 
token(const std::unique_ptr<expression>& expr) = delete;
 
token(std::unique_ptr<expression>&& expr)
: type_(token_type::expression)
{
new (&expr_) std::unique_ptr<expression>(std::move(expr));
}
 
token(token&& other)
{
construct(std::forward<token>(other));
}
 
token& operator=(const token& other) = delete;
 
token& operator=(token&& other)
{
if (&other != this)
{
if (type_ == other.type_)
{
switch (type_)
{
case token_type::expression:
expr_ = std::move(other.expr_);
break;
case token_type::key:
key_ = std::move(other.key_);
break;
default:
break;
}
}
else
{
destroy();
construct(std::forward<token>(other));
}
}
return *this;
}
 
~token() noexcept
{
destroy();
}
 
token_type type() const
{
return type_;
}
 
void construct(token&& other)
{
type_ = other.type_;
switch (type_)
{
case token_type::expression:
new (&expr_) std::unique_ptr<expression>(std::move(other.expr_));
break;
case token_type::key:
new (&key_) std::string(std::move(other.key_));
break;
default:
break;
}
}
 
void destroy() noexcept
{
switch (type_)
{
case token_type::expression:
expr_.~unique_ptr();
break;
case token_type::key:
key_.~basic_string();
break;
default:
break;
}
}
};
 
std::vector<token> output_stack;
 
void push_token(token&& tok)
{
switch (tok.type())
{
case token_type::lbrace:
case token_type::key:
case token_type::expression:
output_stack.push_back(std::move(tok));
break;
case token_type::rbrace:
{
auto it = output_stack.rbegin();
while (it != output_stack.rend() && it->type() != token_type::lbrace)
{
assert(it->type() == token_type::expression);
auto expr = std::move(output_stack.back().expr_);
++it;
assert(it->type() == token_type::key);
auto key = std::move(output_stack.back().key_);
++it;
}
assert(it != output_stack.rend());
output_stack.erase(it.base(), output_stack.end());
assert(it->type() == token_type::lbrace);
output_stack.pop_back();
break;
}
}
}
}
 
int main()
{
push_token(token(lbrace_arg));
push_token(token("foo"));
push_token(token(std::make_unique<expression>()));
push_token(token(rbrace_arg));
}
Sam <sam@email-scan.com>: Jun 21 11:34PM -0400

Daniel P writes:
 
> someone explain?
 
> vc fails with a read access violation after stepping past (*), and gcc fails
> with Error in `./test': free(): invalid pointer: 0x0000000001984b88
 
I see two possible directions here.
 
1) Burn a crapton of time debugging this, to get to the bottom of it.
 
2) Upgrade your compiler to at least the C++17 level, and replace the entire
token class with:
 
typedef std::variant<std::monostate, lbrace_arg_t, rbrace_arg_t,
std::unique_ptr<expression>,
std::string> token;
 
For C++14 or earlier, Boost's version will also work. Either does the same
thing. I don't see much of a reason to reinvent this wheel.
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Jun 22 06:15AM +0200

On 22.06.2020 03:33, Daniel P wrote:
> push_token(token(std::make_unique<expression>()));
> push_token(token(rbrace_arg));
> }
 
This seems to "work":
 
 
case token_type::rbrace:
{
auto it = output_stack.rbegin();
while (it->type() != token_type::lbrace)
{
assert(it->type() == token_type::expression);
auto expr = std::move(it->expr_);
++it;
assert(it->type() == token_type::key);
auto key = std::move(it->key_);
++it;
}
assert(it->type() == token_type::lbrace);
output_stack.erase(it.base(), output_stack.end());
output_stack.pop_back();
break;
}
 
 
It seems connected to moving twice or more from `output_stack.back()`.
 
If this solves your problem then it's proof that I can fix code without
understanding it.
 
 
- Alf
 
PS: The two statements before `break;` can probably be expressed with
just one vector operation, more clean IMHO.
 
PPS: Consider using `std::variant` instead of creating your own
discriminated union.
Daniel P <danielaparker@gmail.com>: Jun 21 09:22PM -0700

On Sunday, June 21, 2020 at 11:35:04 PM UTC-4, Sam wrote:
> std::string> token;
 
> For C++14 or earlier, Boost's version will also work. Either does the same
> thing. I don't see much of a reason to reinvent this wheel.
 
variant isn't an option, C++11 needs to be supported. Besides, I need to
understand what's happening here.
 
Daniel
Daniel P <danielaparker@gmail.com>: Jun 21 09:34PM -0700

On Monday, June 22, 2020 at 12:15:39 AM UTC-4, Alf P. Steinbach wrote:
 
> It seems connected to moving twice or more from `output_stack.back()`.
 
> If this solves your problem then it's proof that I can fix code without
> understanding it.
 
Alf, A _BIG_ thanks. That was a bug, and I couldn't see it. Very much
appreciated.
 
Daniel
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: