Friday, June 18, 2021

Digest for comp.lang.c++@googlegroups.com - 20 updates in 1 topic

"Öö Tiib" <ootiib@hot.ee>: Jun 17 04:51PM -0700

On Thursday, 17 June 2021 at 08:35:26 UTC+3, Juha Nieminen wrote:
> Öö Tiib <oot...@hot.ee> wrote:
> > and so I'm stuck in C++14.
> My condolences.
 
No condolescences are mine ... to those who have to use C++17 and so their
code is formally full of undefined behaviors.
Sam <sam@email-scan.com>: Jun 17 08:19PM -0400

Öö Tiib writes:
 
> > My condolences.
 
> No condolescences are mine ... to those who have to use C++17 and so their
> code is formally full of undefined behaviors.
 
C++17 isn't that bad. std::variant alone is worth the price of the admission.
"Öö Tiib" <ootiib@hot.ee>: Jun 17 06:22PM -0700

On Friday, 18 June 2021 at 03:19:18 UTC+3, Sam wrote:
 
> > No condolescences are mine ... to those who have to use C++17 and so their
> > code is formally full of undefined behaviors.
> C++17 isn't that bad. std::variant alone is worth the price of the admission.
 
I just continue using boost::variant and boost::optional. I have used those
more than ten years. Some of my code uses boost asio, other boost intrusive
and I have some boost graph usage too so it does not matter much that
optional and variant are in std now.
All these implementations are undefined behavior by C++17 but if I do
not use C++17 compilers or C++14 compilers to what defects of C++17
were back-ported then problem is solved.
David Brown <david.brown@hesbynett.no>: Jun 18 08:56AM +0200

> types, no JSON or XML libraries that don't reimplement unicode
> encoding validation and conversion ...
 
> Daniel
 
That all depends on your needs. At the moment, I for one have no need
for anything like that in C++. When I want JSON stuff, or SQL, I use
Python - it is much better for such high level things.
 
Much of this could change once reflection and metaclasses are in place
in C++. Currently, it is impossible (AFAIK) to make a "to_json"
function that could take a wide variety of types and structures and
generate a JSON object - you need to provide a schema of some kind for
it. Metaclasses would let you do that automatically. Similarly, they
could let you write a single description of the columns of a database
table, and use that for queries as well as generating classes and
functions to handle them. This is the kind of language feature that
causes people to choose Python or PHP for such tasks.
 
There would also probably be much to be gained by an "official"
repository of C++ libraries, to provide some of the things that
languages like Python can provide in their standard library, but which
definitely should not be in the main C++ standard library.
red floyd <no.spam.here@its.invalid>: Jun 18 12:18AM -0700

On 6/17/2021 4:51 PM, Öö Tiib wrote:
>> My condolences.
 
> No condolescences are mine ... to those who have to use C++17 and so their
> code is formally full of undefined behaviors.
 
OK, I'm confused. What used to be defined behavior that is now UB?
"Öö Tiib" <ootiib@hot.ee>: Jun 18 02:06AM -0700

On Friday, 18 June 2021 at 10:18:54 UTC+3, red floyd wrote:
 
> > No condolescences are mine ... to those who have to use C++17 and so their
> > code is formally full of undefined behaviors.
 
> OK, I'm confused. What used to be defined behavior that is now UB?
 
Basically lot of things with pointer-interconvertibility, constexpr and
strengthening several implementation-specified to undefined.
Even std::vector is magical now and not possible to implement in standard
C++, nothing to talk of those boost classes I mentioned. Or how you
implement std::vector::data() when there are no array of elements
and so you can't provide pointer to that array?
Additionally they did on lot of occasions in std::lawyer::butcher::speak:
"behavior-changing defect reports were applied retroactively to previously
published C++ standards".
It means they back-butchering their defects of C++17 into previous standards,
so to be safe one needs to use compilers released before implementing
compliance with that butchery.
MrSpook_Zp_@opm5ve6jyhq.ac.uk: Jun 18 09:22AM

On Thu, 17 Jun 2021 13:45:33 -0700 (PDT)
>no comprehensive CBOR or BSON or SQL libraries that map to standard
>types, no JSON or XML libraries that don't reimplement unicode
>encoding validation and conversion ...
 
Don't project your own requirements onto others. I don't think I've ever
once thought I've needed any of that in the language in the last 20 years
since its all solved either by posix or freely available libraries.
MrSpook_6a2az@yxcggolr9p.com: Jun 18 09:24AM

On Thu, 17 Jun 2021 18:22:38 -0700 (PDT)
>more than ten years. Some of my code uses boost asio, other boost intrusive
>and I have some boost graph usage too so it does not matter much that=20
>optional and variant are in std now.
 
I won't let that bloatware anywhere near any of my projects. Boost can go
die in a corner for all I care.
Sam <sam@email-scan.com>: Jun 18 08:20AM -0400

> >optional and variant are in std now.
 
> I won't let that bloatware anywhere near any of my projects. Boost can go
> die in a corner for all I care.
 
That was mostly my assessment of boost about 15 years ago. It's arcane,
convoluted mess. Some bits of its eventually made it into the C++ standard.
variant/optional are rare exceptions, they're quite useful. But the rest of
it is crap, including boost's poster child: shared_ptr. What a completely
worthless pile of junk. Whoever thought of that must've just had a bad acid
trip. That's the only explanation for requiring an extra allocation for
every object, and making shared_ptr actually be two separate pointers (or
having to access the referenced object via two hops, at implementation's
choice); and lacking any semblance of const-correctness. The separate
allocation does make it possible to use it with any class, that's it's only
benefit. But that doesn't come anywhere close to making up for its many
shortcoming and design flaws.
Manfred <noname@add.invalid>: Jun 18 03:23PM +0200

On 6/17/2021 11:15 PM, Real Troll wrote:
 
>> C++ remains comparatively
>> impoverished because of the absence of standard types
 
> In fact C++ remains impoverished because of its bureaucratic process of approving anything to be part of the standard!.
 
Bureaucracy is a problem yes, but lack of consensus and incoherence is
the real problem of the committee, IMO.
In fact, in my opinion, they have approved too many questionable
features, and created too much of a problem with consensus on the really
important ones - the history of "concepts" is paradigmatic in that
sense. The quality of the result is IMO less than optimal for this exact
reason.
 
 
> When C# had such a body, nothing was achieved and so Microsoft decided to go it alone and now it has become one of the best programming languages. It has a standard called ECMA-334
 
As far as I understand C# is a Microsoft product, and its
standardization was promoted by Microsoft in what seems to me a mere PR
operation.
 
> <https://www.ecma-international.org/publications-and-standards/standards/ecma-334/> but It is not as bureaucratic as ISO or some other standard bodies. I think even Suter and Bjarne Stroustrup have given up on the body currently in-charge of the C++ Standards. Its become a laughing stock of dedicated programmers around the world who have started writing their own standards based on what C++ does but also what other languages are doing.
 
I don't know about Sutter (whom I am not completely pleased with his
results in the language), but I have got the same impression that
Stroustrup is backing off after one of his latest interviews.
David Brown <david.brown@hesbynett.no>: Jun 18 03:38PM +0200

On 18/06/2021 14:20, Sam wrote:
> possible to use it with any class, that's it's only benefit. But that
> doesn't come anywhere close to making up for its many shortcoming and
> design flaws.
 
Boost tries to make new classes, functions and other features that
people would find useful in C++ programming. It is not uncommon that
the implementation is more than a little ugly with complex macros, and
is often less efficient than you might imagine. But the libraries are
nonetheless useful to people.
 
The C++ committee use these for inspiration and prototyping. The look
at a class such as boost's variant and optional, and see that people
like it. The wonder how it could be added to the standard library, how
it could be better for the user, how it could be made safer or more
efficient. The wonder what language features would be needed in the
core of C++ in order to get there. This is a major influence on how the
language progresses - it gets features that real users are finding
useful in boost.
 
Oh, and for shared_ptr, there is no option but to have a certain level
of indirection - you need a control block in addition to the object
itself. But often you can get a single allocation for both using
std::make_shared, which results in more efficient allocation (and
deallocation) as well as better cache locality.
Paavo Helde <myfirstname@osa.pri.ee>: Jun 18 05:46PM +0300

18.06.2021 15:20 Sam kirjutas:
> possible to use it with any class, that's it's only benefit. But that
> doesn't come anywhere close to making up for its many shortcoming and
> design flaws.
 
Ever heard of std::make_shared() and std::allocate_shared()? This
answers most of your objections (alas, in expense of having
undecipherable error messages if anything is amiss).
"daniel...@gmail.com" <danielaparker@gmail.com>: Jun 18 08:06AM -0700

On Friday, June 18, 2021 at 2:56:34 AM UTC-4, David Brown wrote:
> > encoding validation and conversion ...
 
> That all depends on your needs. At the moment, I for one have no need
> for anything like that in C++.
 
It's not about your needs, it's about how the absence of fundamental types
in the C++ standard library impedes the emergence of libraries. Writing a
C++ library to process standard or de facto standard data formats
such as JSON, XML, CBOR, BSON, SQL is much more work and the results are
far less satisfactory than in other languages that have support for
fundamental types such as int128, uint128, float128, big_int, big_decimal,
bytes to some unicode encoding, some unicode encoding to bytes,
validation of unicode encoding, etc. And almost all other modern languages
have these things. It is not only a burden for library writers, it is also a burden
for library users, who have to convert whatever the library uses for int128,
uint128, float128, big_int, big_decimal etc. into what they use.
> function that could take a wide variety of types and structures and
> generate a JSON object - you need to provide a schema of some kind for
> it.
 
Hardly impossible, rather, it's quite common. Modern C++ JSON/CBOR/BSON
etc. libraries tend to fall into two groups, ones that are focused primarily on
performance (processing gigabytes of JSON per second), notably simdjson,
and ones that support something like
 
MyType val = from_json<MyType>(JSON input);
to_json(val, JSON output);
 
The latter group supports conversion between JSON text and user defined
(not generated) types through user extensible traits.
 
> could let you write a single description of the columns of a database
> table, and use that for queries as well as generating classes and
> functions to handle them.
 
Yes, I follow the SG-7 compile-time reflection committee mailing list, am
familiar with the The Syntax of Static Reflection proposal ( P2320R0), and have
experimented with the clang compiler fork that implements the proposal.
You may see it in C++ 2026. New libraries may start emerging a couple of years
later that take advantage of this support.
 
P2320R0 doesn't entirely address the issue of UDT/serialized format conversion,
though. C++ will still need a way to tag information to a C++ entity, such as
serialized names where these differ from member data names. Most languages
that support reflection allow this through attributes. C++ currently only
supports built-in attributes. Maybe we'll have something in C++ 2029?

And metaclasses don't address this issue: a deficiency of fundamental
standard types to map things to that most other languages have.
 
> repository of C++ libraries, to provide some of the things that
> languages like Python can provide in their standard library, but which
> definitely should not be in the main C++ standard library.
 
What things? Are you suggesting that int128, uint128, float128, big_decimal,
big_int, and unicode encoding validators or converters should "definitely
not be in the main C++ standard library"?
 
Daniel
David Brown <david.brown@hesbynett.no>: Jun 18 05:41PM +0200

> fundamental types such as int128, uint128, float128, big_int, big_decimal,
> bytes to some unicode encoding, some unicode encoding to bytes,
> validation of unicode encoding, etc.
 
I haven't tried to implement such libraries in C++. But it is not those
types that are the sticking points. These can be made as classes if you
like. (Built-in types might be neater or more efficient, of course.)
 
To make a good JSON (or whatever) library, you want to be able to write:
 
struct data {
int x;
string s;
};
 
data d;
 
auto j = to_json(d);
 
and have the result {"x" : 123, "s" : "Hello, world!"}.
 
The key missing feature is a way for "to_json" to access the structure
details.
 
Languages which make JSON, etc., simple have the introspection needed.
(Many are dynamic languages, which helps here too.)
 
> supports built-in attributes. Maybe we'll have something in C++ 2029?
 
> And metaclasses don't address this issue: a deficiency of fundamental
> standard types to map things to that most other languages have.
 
I don't disagree that additional standard types here could be useful - I
just don't think those are the sticking points.
 
 
> What things? Are you suggesting that int128, uint128, float128, big_decimal,
> big_int, and unicode encoding validators or converters should "definitely
> not be in the main C++ standard library"?
 
I certainly don't want them in the libraries /I/ use on small embedded
systems - there should perhaps be a clearer distinction of what parts of
the standard library are required for different types of targets rather
than the all-or-nothing permission of freestanding vs. hosted.
 
But no, I am thinking of the kinds of convenient libraries that are
common in the standard libraries for Python, PHP, and the like - https
support, SMTP, jpeg, zip, etc. If I want to write a Python program to
send a zip of some files by email, it is short and simple. Doing it in
C++ would be a major effort. However, such libraries don't belong in
C++ standard library (IMHO) - but an official repository of common
libraries would be useful. (Other modern languages have them.)
MrSpook_gavL@es9w71p.tv: Jun 18 03:53PM

On Fri, 18 Jun 2021 08:06:55 -0700 (PDT)
>in the C++ standard library impedes the emergence of libraries. Writing a
>C++ library to process standard or de facto standard data formats
>such as JSON, XML, CBOR, BSON, SQL is much more work and the results are
 
Why? What do you think typedefs (or the silly using syntax) are for?
 
>far less satisfactory than in other languages that have support for
>fundamental types such as int128, uint128, float128, big_int, big_decimal,
 
At least C++ has unsigned types which is more than java managed for 2 decades.
 
>serialized names where these differ from member data names. Most languages
>that support reflection allow this through attributes. C++ currently only
>supports built-in attributes. Maybe we'll have something in C++ 2029?
 
What can reflection do that typeid(), reinterpret_cast or just a simple type
variable in a base class can't?
scott@slp53.sl.home (Scott Lurndal): Jun 18 04:06PM

>>supports built-in attributes. Maybe we'll have something in C++ 2029?
 
>What can reflection do that typeid(), reinterpret_cast or just a simple type
>variable in a base class can't?
 
Iterate over the members of a class/struct dynamically, for example.
"daniel...@gmail.com" <danielaparker@gmail.com>: Jun 18 02:31PM -0700

On Friday, June 18, 2021 at 11:42:11 AM UTC-4, David Brown wrote:
 
 
> and have the result {"x" : 123, "s" : "Hello, world!"}.
 
> The key missing feature is a way for "to_json" to access the structure
> details.
 
Most "modern" JSON libraries - e.g. nlohmann, jsoncons, Spotify JSON,
taojson, ThorsSerializer - support that through user defined traits
that describe what to do with types that the library doesn't know about.
Several of the above include convenience macros for generating the
traits, e.g. jsoncons suppports
 
JSONCONS_ALL_MEMBER_TRAITS(data, x, s)
 
data d{123, "Hello, world!"};
 
std::string s;
encode_json(d, s);
 
Result: {"s":"Hello,world!","x":123}
 
P2320R0 will allow libraries to implement that simple case without any
need for the user to declare traits. Compile time reflection and metaclasses,
however, won't be enough if e.g. member variable names and desired JSON names
differ, and the desired output is {"String" : "Hello, world!", "X" : 123}.
 
Other languages support that with attributes, e.g. a C# example
 
public class Videogame
{
[JsonProperty("name")]
public string Name { get; set; }
 
[JsonProperty("release_date")]
public DateTime ReleaseDate { get; set; }
}
 
But C++ currently only supports built in attributes. So until we have
user defined attributes, which is being talked about but looks to be a
long ways away, we'll still need traits to tag information to a C++
class for all but the simplest problems.
 
 
> Languages which make JSON, etc., simple have the introspection needed.
> (Many are dynamic languages, which helps here too.)
 
Not all, rust serde uses traits rather than reflection to support encode/decode.
 
 
> I don't disagree that additional standard types here could be useful - I
> just don't think those are the sticking points.
 
It's factual that the availability of C++ github libraries that support standardized
data formats such as JSON, CBOR, BSON etc is way behind that of other languages.
It's noted that rust serde, which is far more capable than any comparable
library in C++, relies on traits rather than reflection for encode/decode,
but rust does supply all the basic fundamental types, and unicode validation
and conversion functions. rust also has user defined attributes and a better
macro language, which helps. But the most basic thing is to have types to map
into, types that are agreeable to both the library author and library user,
standard types.
Sam <sam@email-scan.com>: Jun 18 05:41PM -0400

Paavo Helde writes:
 
 
> Ever heard of std::make_shared() and std::allocate_shared()? This answers
> most of your objections (alas, in expense of having undecipherable error
> messages if anything is amiss).
 
Ummm… std::make_shared leaves most of shared_ptr's problems untouched. You
still get the same fugly shared_ptr implementation, with two pointers
instead of one. std::allocate_shared addresses some edge cases that are
quite rare, but the end result is still a fugly shared_ptr. The problems
with shared_ptr are fundamental, and are beyond the reach of fancy
constructors and factories.
Sam <sam@email-scan.com>: Jun 18 06:01PM -0400

David Brown writes:
 
> itself. But often you can get a single allocation for both using
> std::make_shared, which results in more efficient allocation (and
> deallocation) as well as better cache locality.
 
Since the end result of make_shared must be a 100% compatible, stock
shared_ptr you still end up having to carry two pointers on your back
instead of one, for no good reason.
 
It's true that there is no other option, given the current design of
shared_ptr. I fall into the object super-root fan club. It's true that this
means that you can't just arbitrary shared_ptr-ify any class, but most
formally inherit from an object root class; and a few other minor drawbacks.
But I think this is a better design, and offers a number of major
advantages, like cost-free smart pointer const-correctness. This is how Java
does objects, and C++ can benefit from learning a few things from Java
(including non-broken exception-correctness that's enforced at compile time,
but I digress).
 
Furthermore, we already had iterator and const_iterator. Why do we need to
have shared_ptr<const Object> instead of const_shared_ptr<Object>?
Furthermore, shared_ptr implementation tend to really suck at supporting
const-correctness. Passing a shared_ptr<Object> to a function that promises,
by contract, to not modify the object, hence its parameter is
shared_ptr<const Object> – this requires a construction of a temporary, and
a bunch of utterly pointless reference counting. This is completely
unnecessary.
 
shared_ptr<Object> should inherit from shared_ptr<const Object>, so
const_correctness comes at zero const, instead of this overhead.
Furthermore, dereferencing a null shared_ptr<Object> is still undefined
behavior.
 
This is stupid. shared_ptr should throw an exception instead. You say that
checking for a null pointer in operator* and operator-> is pointless
overhead? I agree. Which is why you should have both shared_ref and
shared_ptr, with shared_ref enforcing, by contract, a non-null pointer (no
default constructor, etc…), so its operator* and operator-> is guaranteed
not to dereference a null pointer and does not impose any overhead. It now
becomes obvious that shared_ptr is constructible from shared_ref, and
shared_ref is constructible from shared_ptr (with a null pointer check, that
throws an exception).
 
Now you can enforce, at compile-time, a non-null smart pointer.
 
The current shared_ptr is a mess, and is beyond repair.
Ian Collins <ian-news@hotmail.com>: Jun 19 11:10AM +1200

On 19/06/2021 03:41, David Brown wrote:
 
> and have the result {"x" : 123, "s" : "Hello, world!"}.
 
> The key missing feature is a way for "to_json" to access the structure
> details.
 
The same argument can be applied to all forms of serialisation, not just
common data formats.
 
There is more to working with the likes of JSON that native object
serialisation, much of my code works with the JSON object directly
without any corresponding native objects.
 
What C++ dues allow, which other languages don't, is code like (from my
JSON library unit tests):
 
object["one"]["two"]["three"]["four"] = 42;
 
CPPUNIT_ASSERT_EQUAL( 42, object["one"]["two"]["three"]["four"] );
 
and
 
object["attributes"][0]["member"] = "child";
 
CPPUNIT_ASSERT_EQUAL( "child", object["attributes"][0]["member"] );
 
--
Ian.
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: