Monday, November 27, 2017

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

"James R. Kuyper" <jameskuyper@verizon.net>: Nov 27 09:59AM -0500

On 11/24/2017 07:25 AM, David Brown wrote:
>> DS = /* as above, but for the destructor */
 
>> return make_tuple( DC, CC, CA, MC, MA, DS ); }
 
> I'm not sure what your function is supposed to do here,
 
I suspect that he's indirectly asking about the rules determining
whether or not various special member functions will be implicitly
declared. He's asking that those rules be expressed in the form of C++
logical expressions.
jacob navia <jacob@jacob.remcomp.fr>: Nov 27 10:02PM +0100

Le 24/11/2017 à 12:49, Stefan Ram a écrit :
> extend/improve/correct the parts given below?
 
> auto explain
> ( bool DCu /* whether a default constructor is user-provided */,
This object property is (as far as I know) only visible by the reader of
the program. Either you or the compiler. I can't figure out how a C++
expression could give you that information, since it is in the
declaration of the object, in the source code of the program.
 
Solutions vary:
 
1) You hack gcc to write into a file the data you want and you compile
your program with your hacked compiler.
Requisites: You must be a good gcc hacker, know C++ and C very well, etc.
 
2) You get an executable with your class and read the debug information.
There you will find all answers (maybe).
You can hack the gdb code to extract the debug info processing module
and hack it to print what you want in a file.
Requisites: C language, and some weeks of work. Doable.
 
3) You can use reflection to build nested templates and preprocessor
macros to iterate through all the fields of the class definition. Then,
you could hack those macros. Look in
 
http://pfultz2.com/blog/2012/07/31/reflection-in-under-100-lines/
 
That is a much easier way, since it would only mean to change the macros
to figure out when the constructor is being defined, and if it is not,
you know it is not being defined... I can't do that but maybe is doable.
 
4) Generate a program for each class you want to investigate, that
includes the right headers and creates an object of that class. Call the
destructor or somehow do an action that can either provoke a compiler
error, or pass compilation. You get the return code of the gcc process
and then interpret it accordingly. That is much easier than all
solutions above, but...
 
WHY DO YOU WANT TO DO THIS?
 
Explain.
 
Explain above all when your function is supposed to run. At compile time
when all this info is available? Or at run time, when it is no longer
visible?
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Nov 27 08:20AM +0100

On 11/26/2017 10:28 PM, Vir Campestris wrote:
>> How do you feel about using it for loop variables:
 
>> for(auto it = foo.begin(); it  foo.end(); ++i) {}
 
> Is that an iterator or a const_iterator?
 
Explicitly writing out the iterator type can be verbose and brittle, and
so I wouldn't do that, but the question of how to communicate the
constness of the iterator's referent is interesting.
 
Well it wouldn't be interesting if the iterator referent constness was
always apparent from the constness of the collection. But e.g. with a
`std::set` the iterator referent (set item) is `const` regardless of the
constness of the set itself. And the other way, a `const` collection
producing iterators with non-`const` referents, can also, at least in
principle, occur, e.g. when the collection is a begin/end-pair proxy for
accessing items of some other collection.
 
When the loop can be expressed as a range based loop one can easily
communicate and enforce constness of the items:
 
for( auto const& item : foo ) //...
 
The other way can also easily be communicated,
 
for( auto& mutable_item : foo )
 
… but not so easily enforced:
 
for( auto& mutable_item : foo )
{
static_assert( not is_const_v<remove_reference_t<decltype(
mutable_item )>> );
//...
}
 
To help with enforcement one may therefore define e.g.
 
template< class Type >
void assert_is_mutable( Type& )
{
static_assert( not is_const_v<Type>, "The object must be
mutable" );
}
 
… and then write
 
for( auto& item : foo )
{
assert_is_mutable( item );
//...
}
 
The last approach works also for the original problem, by defining
 
template< class Type >
void assert_is_const( Type& )
{
static_assert( is_const_v<Type>, "The object must const" );
}
 
… and then writing
 
for( auto it = foo.begin(); it != foo.end(); ++it )
{
assert_is_const( *it );
//...
}
 
Doing this instead as expressions fed to `static_assert` runs into
problems. I think it would be nice if a call of a `constexpr` function F
with an actual argument that involved a call of a non-`constexpr`
function, could yield a `constexpr` result when only the type of the
actual argument was used to produce the result (or perhaps simpler, if
the formal argument in F was not named). This could solve :-) also the
problem with C++17 `std::size`, which can't formally be applied to a
formal argument array reference, which IMHO is just über-silly.
 
 
> casual reader can't tell at a glance what x really is. And even when the
> tools are working you usually have to "hover" on the variable, then
> wait, to see. Which is slower.
 
Much of the point is that one really doesn't care about the exact type
of an iterator, and that it's desirable to /not/ know, because using
that knowledge just makes the code brittle and possibly non-portable.
 
 
> [snip]
> 2) I don't always agree with Herb. Nearly always, but not every time!
 
NAAAH - Nearly Almost Always Auto, Herb.
 
 
Cheers!,
 
- Alf
Gareth Owen <gwowen@gmail.com>: Nov 27 07:27PM

>> iterator - just that you can iterate with it. That's why they're a good
>> abstraction[0].
 
> I bet you put your curly brackets in the wrong place too... :)
 
#define BEGIN {
#define END }
 
...
"Öö Tiib" <ootiib@hot.ee>: Nov 27 08:03AM -0800

I can hardly imagine any reasons to throw from destructor, move constructor
or move assignment.
 
The destructor is implicitly noexcept unless there are bases or members
that have noexcept(false) destructors.
 
Does anyone know why move constructor and move assignment are implicitly
noexcept(false)? By default (e.g. = default) these are also noexcept(true)
when possible like the destructor is.
Daniel <danielaparker@gmail.com>: Nov 27 08:40AM -0800

On Monday, November 27, 2017 at 11:04:00 AM UTC-5, Öö Tiib wrote:
> I can hardly imagine any reasons to throw from ... move constructor
> or move assignment.
 
One reason, if move must replace an allocator, and propagate_on_container_move_assignment::value is false, the implementation may want to perform a copy, then copy can throw.
 
Daniel
ram@zedat.fu-berlin.de (Stefan Ram): Nov 27 04:06PM

>whether or not various special member functions will be implicitly
>declared. He's asking that those rules be expressed in the form of C++
>logical expressions.
 
Yes!
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Nov 27 09:09AM +0100

On 11/26/2017 6:35 AM, Stefan Ram wrote:
> ::std::string const a[ 3 ]= b;
> ^
 
> What is this?
 
No such thing as direct raw array copying in standard C++.
 
 
> gcc compiled and executed the program without
> a diagnostic message,
 
Via a language extension.
 
 
> and then clang says there is an error?
 
clang is more conforming /by default/.
 
Raw array copying is supported for raw arrays as data members, e.g. as
in `std::array`.
 
#include <array>
#include <iostream>
#include <string>
using namespace std;
 
auto main()
-> int
{
const array<string, 3> b{ "a", "b", "c" };
const array<string, 3> a = b;
 
cout
<< "\""
<< a[0] << ", "
<< a[1] << ", "
<< a[2]
<< "\"." << endl;
}
 
In this rewrite:
 
• Including <ostream> is not formally necessary with C++11 and later, so
that's not done here.
• Explicitly converting the initializer items to `string` is also
unnecessary, so that's not done here.
• Using raw string literals is unnecessary, so that's not done here.
 
And of course, prefixing all standard library items with `::std::` is
unnecessary.
 
Cheers & hth.,
 
- ALf
leigh.v.johnston@googlemail.com: Nov 27 04:32AM -0800

"::std::" prefix is unnecessary but "std::" isn't as "using namespace std;" is egregious.
 
/Leigh
Real Troll <real.troll@trolls.com>: Nov 27 04:10AM -0400

Microsoft has for the very first time Introduced "Nullable Reference
Types in C#" Apparently everybody knew about this since 1965 but nobody
thought of implementing it!!!!! Now this is Microsoft speaking.
 
<https://blogs.msdn.microsoft.com/dotnet/2017/11/15/nullable-reference-types-in-csharp/?utm_source=vs_developer_news&utm_medium=referral>
Chris Ahlstrom <OFeem1987@teleworm.us>: Nov 27 05:22AM -0500

Real Troll wrote this copyrighted missive and expects royalties:
 
> Types in C#" Apparently everybody knew about this since 1965 but nobody
> thought of implementing it!!!!! Now this is Microsoft speaking.
 
> <https://blogs.msdn.microsoft.com/dotnet/2017/11/15/nullable-reference-types-in-csharp/?utm_source=vs_developer_news&utm_medium=referral>
 
I always get a chuckle out of languages that purport to clean up the
"messes" of C and C++, and replace them with something even more
problematic.
 
--
Good news. Ten weeks from Friday will be a pretty good day.
"Öö Tiib" <ootiib@hot.ee>: Nov 27 04:25AM -0800

On Monday, 27 November 2017 12:35:35 UTC+2, Chris Ahlstrom wrote:
 
> I always get a chuckle out of languages that purport to clean up the
> "messes" of C and C++, and replace them with something even more
> problematic.
 
The languages that add "optional" or "nullable" support into core
language win the opportunity to design it in diagnosable and
optimizable manner.
 
The library solution like 'std::optional' of C++ has its inefficiency
inbuilt. For example 'optional::value_or'. It can't leave its argument
unevaluated when this has value and so it is innately inefficient.
People have to use 'some_optional ? *some_optional : argument()'
instead of 'some_optional.value_or(argument())' always.
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: