Monday, June 12, 2017

Digest for comp.lang.c++@googlegroups.com - 25 updates in 7 topics

Vir Campestris <vir.campestris@invalid.invalid>: Jun 12 09:28PM +0100

Why is it that when I call a function that returns a reference, and
assign the result to an auto, it copies the value rather than declaring
the auto as a reference?
 
e.g.
 
std::vector<char> v;
...
auto c = v[0];
auto& r = v[0]
 
c is a char; to get a reference I must explicitly say so.
 
Andy
"Öö Tiib" <ootiib@hot.ee>: Jun 12 01:47AM -0700

On Sunday, 11 June 2017 00:14:28 UTC+3, JiiPee wrote:
> variable if its a pointer. If there any way to solve the problem that
> assignment cannot be done If I use your reference method? how can i copy
> Point's if it has that reference?
 
Note that the situation you describe does not make sense.
 
* There is a "game" and there are "player"s of it. Ok so far with me.
* Now somehow one of those "player"s can be without "game" (or
with already ended and destroyed game). How?
* Also the "points" of that particular "player" can somehow change
without it being in actually existing "game". How?
 
So now the "player" tries to notify to unexisting "game" that the points
changed. The situation itself indicates deeper insanity somewhere.
JiiPee <no@notvalid.com>: Jun 12 08:41PM +0100

On 12/06/2017 09:47, Öö Tiib wrote:
 
> * There is a "game" and there are "player"s of it. Ok so far with me.
> * Now somehow one of those "player"s can be without "game" (or
> with already ended and destroyed game). How?
 
There are permanently stored players (which are in a file) and then from
those are selected the ones which are in a particular game. A player can
be removed from the game even in the middle of the game. And all of the
functionalities use the same Player class.
 
> * Also the "points" of that particular "player" can somehow change
> without it being in actually existing "game". How?
 
No the points are not changed outside the player being in a game.
Players points are onlyl changed if it is in a game. Although other
variables like the title of the player and the name of the player can
possibly be modified even without being in a game (just modifying the
players database).
 
> So now the "player" tries to notify to unexisting "game" that the points
> changed. The situation itself indicates deeper insanity somewhere.
 
If the game is in a state of "modifying players data", then I guess it
does not need to be in any game at that moment. Also logically speaking
so. If you modify a certain database -players name, why would it need to
be in a game?
Juha Nieminen <nospam@thanks.invalid>: Jun 12 08:07AM

> 'Insert(data,n)' creates a node in the nth position with a payload
> 'data'. My question is why the memory allocated on the heap is not
> freed before the control is returned to the main function.
 
By design. The 'new' keyword allocates memory that's precisely designed
to outlive the scope where it was allocated.
 
Of course since C++ does not have any sort of garbage collection
mechanism for heap-allocated memory blocks, it's up to the code to
eventually free it explicitly, or else it will remain allocated
for the remaining of the runtime of the program.
 
(C++ offers several mechanisms to manage that more easily and safely,
such as using std::unique_ptr or std::shared_ptr, or doing the
allocation within a class that automatically manages freeing that
memory, such as what the standard data containers like std::vector
and std::list do.)
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Jun 12 10:13AM +0200

On 12-Jun-17 10:07 AM, Juha Nieminen wrote:
> [snip]
> Of course since C++ does not have any sort of garbage collection
> mechanism for heap-allocated memory blocks,
 
C++11 added support for garbage collection.
 
I only know of the Boehm collector.
 
And sorry, I haven't used it, but as I recall James Kanze had some
experience with it in the C++03 days (yes, before the language added
support for it!).
 
 
Cheers & hth.,
 
- Alf
Ian Collins <ian-news@hotmail.com>: Jun 12 08:57PM +1200

On 06/12/17 08:13 PM, Alf P. Steinbach wrote:
 
> And sorry, I haven't used it, but as I recall James Kanze had some
> experience with it in the C++03 days (yes, before the language added
> support for it!).
 
The Boehm collector was well supported in the old Sun tools, back before
the first standard! I for one was very disappointed with support was
discontinued.
 
 
--
Ian
Juha Nieminen <nospam@thanks.invalid>: Jun 12 12:59PM

> C++11 added support for garbage collection.
 
No, it didn't. It allows for the implementation to do some
implementation-specific stuff for garbage collection, but
it's not guaranteed in any way.
Melzzzzz <Melzzzzz@zzzzz.com>: Jun 12 01:17PM


> No, it didn't. It allows for the implementation to do some
> implementation-specific stuff for garbage collection, but
> it's not guaranteed in any way.
Why all the fuss with GC? Rust dropped it, Apple dropped it, and lot of
people demanding D to have GC free stdlib?
 
--
press any key to continue or any other to quit...
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Jun 12 07:41PM +0200

On 12-Jun-17 2:59 PM, Juha Nieminen wrote:
> Alf P. Steinbach <alf.p.steinbach+usenet@gmail.com> wrote:
>> C++11 added support for garbage collection.
 
> No, it didn't.
 
Yes it did. E.g. section §20.6.4 called "Pointer safety" is all about
support for garbage collection. In the standard's own words, in §C.2.10,
it's a "Minimal support for garbage-collected regions".
 
 
> It allows for the implementation to do some
> implementation-specific stuff for garbage collection, but
> it's not guaranteed in any way.
 
That appears to be nonsense, at least as support for the previous
assertion. Can you be more specific? Thank you.
 
 
Cheers!,
 
- Alf
"Rick C. Hodgin" <rick.c.hodgin@gmail.com>: Jun 11 05:35PM -0700

> > specific compiler division or sales division for compilers?
 
> Maybe you could contact one of these guys:
> http://cppcast.com/2017/04/udit-patidar-anoop-prabha/
 
After your post I was getting ready to write them, and I thought I would
try something else related to them being Intel employees. I downloaded
a trial version of their current compiler, and they sent me some follow-
up email. I have used that info to try to contact them regarding my
older compiler. I'm hoping that will work.
 
I appreciate your assistance, Brian.
 
Thank you,
Rick C. Hodgin
David Brown <david.brown@hesbynett.no>: Jun 12 08:53AM +0200

On 12/06/17 02:35, Rick C. Hodgin wrote:
> up email. I have used that info to try to contact them regarding my
> older compiler. I'm hoping that will work.
 
> I appreciate your assistance, Brian.
 
Did you not get any response from their normal support page? It may be
that your compiler is too old and the support contract has run out, but
I would expect them to tell you that.
scott@slp53.sl.home (Scott Lurndal): Jun 12 12:42PM

>> users,
 
>They are Intel employees. One of them works on supporting the
>Intel C++ compiler.
 
That doesn't make them the contact point for compiler licensing.
"Rick C. Hodgin" <rick.c.hodgin@gmail.com>: Jun 12 06:27AM -0700

On Friday, June 9, 2017 at 3:02:08 PM UTC-4, David Brown wrote:
> ...the Intel support page for the compiler...
 
Thank you, David. I did not get an initial reply from Intel where I
attempted, so I also went to the forum and posted a message there.
 
You're probably right that it's too old, but if not I would like to
have that compiler as well.
 
Thank you,
Rick C. Hodgin
David Brown <david.brown@hesbynett.no>: Jun 12 04:16PM +0200

On 12/06/17 15:27, Rick C. Hodgin wrote:
>> ...the Intel support page for the compiler...
 
> Thank you, David. I did not get an initial reply from Intel where I
> attempted, so I also went to the forum and posted a message there.
 
Fair enough. When you use the proper support page, you can expect an
answer (even if it is a polite "that product is no longer supported").
But when you send a support request directly to a developer or a member
of the support staff, it is perfectly reasonable for them to ignore the
email. That's why I wanted to push the correct support address on you,
rather than Brian's daft, disrespectful and time-wasting plan of finding
someone who might be an Intel support person via articles they have written.
 
 
> You're probably right that it's too old, but if not I would like to
> have that compiler as well.
 
Sure, I can well appreciate that. Intel's compiler certainly used to be
free for personal use on Linux - I don't know the current state (on
Linux or Windows). Versions of icc are on the godbolt site, which
suggests that at least those versions could be freely used (or Mr.
Godbolt should probably disable them).
 
Juha Nieminen <nospam@thanks.invalid>: Jun 12 07:55AM

>>> #include <assert.h>
 
>> Really?
 
> It's a standard header that defines a macro called `assert`.
 
No, the standard header you are referring to is named cassert.
 
http://en.cppreference.com/w/cpp/header/cassert
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Jun 12 10:08AM +0200

On 12-Jun-17 9:55 AM, Juha Nieminen wrote:
 
>>> Really?
 
>> It's a standard header that defines a macro called `assert`.
 
> No, the standard header you are referring to is named cassert.
 
You're wrong.
 
I suspect you don't understand how this work, so, short summary:
 
1. The C library header <xxx.h> defines some stuff S.
 
2. The C++ library header <cxxx> provides that stuff S in namespace std,
and possibly but not guaranteed in the global namespace. Some small
adjustments are sometimes made, some overloads are sometimes added.
 
3. The C++ library header <xxx.h> provides the stuff S from <cxxx>, in
the global namespace, and possibly but not guaranteed in namespace std.
 
As you can see there are logically three distinct headers, involving two
different languages. The two headers that appear to have the same name,
in points 1 and 3, belong to two different languages and are possibly
distinct files with different content.
 
I SUSPECT, from the otherwise nonsense comments, that you thought I was
referring to 1, when, if you had been fully familiar this, you would
have understood 3, since that's the C++ header.
 
Note also that namespaces don't matter for a macro: macros don't respect
scopes.
 
As I recall C++17 will foil this scheme a little by breaking the
symmetry of 2 and 3 for some new stuff, just to be consistent with its
plethora of other special you'd-never-guess-it! cases.
 
 
> http://en.cppreference.com/w/cpp/header/cassert
 
That presumably & hopefully backs up what I said, not what you said.
 
 
Cheers & hth.,
 
- Alf
Juha Nieminen <nospam@thanks.invalid>: Jun 12 12:57PM

> I SUSPECT, from the otherwise nonsense comments, that you thought I was
> referring to 1, when, if you had been fully familiar this, you would
> have understood 3, since that's the C++ header.
 
Do you know where you can shove your arrogant attitude?
"Fred.Zwarts" <F.Zwarts@KVI.nl>: Jun 12 01:41PM +0200

"Chris Ahlstrom" schreef in bericht news:ohjhmh$e7l$1@dont-email.me...
 
>> Try newer compiler.
 
>gcc/g++ are up to version 6.3 (at least) now.
 
>Maybe Fred doesn't want to pay the license fee to upgrade :-).
 
I have no choice. It is not my system. I have to live with the compiler that
is installed on this system.
Adam Badura <adam.f.badura@gmail.com>: Jun 11 04:40PM -0700

> > programmer-provided values, including repeated values, and maybe even
> > some more.
 
> Sounds like premature generalization. Do you really need all that?
 
In cases I often have to deal with I don't have control over the enum in the first place. Which dismisses your approach entirely. The enum is there, provided by a third party (or close enough) and I have to deal with it.
 
But it doesn't matter in the end I think. My question was not to find alternatives which I already knew quite well. It was to find out why the feature I asked for is not present. And as it seams there are no reasons deeper than just: "no on added it". Or there?
 
> disadvantages objectively: you have likely already dismissed that. So,
> authority arguments it is. That's fallacious, of course, but I don't shy
> away from a few fallacies here and there if they can do good, so:
 
Well, actually I would be more than happy to know "the merits and disadvantages objectively". So I would be grateful if you could direct me to some sources or explain them yourself (although maybe a separate thread would be better for this?).
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Jun 12 04:24AM +0200

On 12-Jun-17 1:40 AM, Adam Badura wrote:
> disadvantages objectively". So I would be grateful if you could
> direct me to some sources or explain them yourself (although maybe a
> separate thread would be better for this?).
 
OK.
 
First lets differentiate between /interface/ and /implementation/.
 
A top-level `const` on a formal argument is never part of a function's
interface, it doesn't matter at all to a caller, and so the C++ rules
make the following two declarations exactly equivalent, denoting the
same function, with the same function type:
 
void foo( int );
void foo( int const );
 
In particular, a header file can contain the declaration (interface)
 
void foo( int );
 
… and an implementation can then contain e.g. (implementation)
 
void foo( int const x ) { gurgle_snap( x ); cout << x << endl; }
 
… which
 
• is an implementation of the former declaration,
 
• clearly outputs the value that's passed to it, because `gurgle_snap`
can't modify `x` because `x` is `const`.
 
The ease with which I can conclude something about the call of the to me
unknown function `gurgle_snap`, and thereby, about the effect of
subsequent code in the function, is, in my opinion, a clear and
objective advantage of `const` on the formal argument (don't mind the
apparent inconsistency between "in my opinion" and "objective", lest we
delve down into an Hofstadteresque infinite regress on the meaning).
I.e. it saves time for maintenance. ~80% of all coding is maintenance.
 
It's the same advantage as for `const` on a local variable.
 
And this advantage is not likely to be there if one doesn't apply
`const` by default, as one's general coding habit.
 
If `foo` is provided via a header-only module, then the `const` will in
practice appear in the declaration of the interface. For a potential
user of `foo` that's redundant wordage, just plain verbosity. Happily
that's what we have tools for, to produce a more pure interface
specification. E.g. that's done in Eiffel, and I think also in Java.
Unfortunately, I'm not familiar with such a tool for C++, although if
one spends a lot of money on licenses of refactoring tools (Rational
Rose comes to mind, but that's from 15 years ago) there will probably be
something like that.
 
So, `const` on value arguments /can/ have a slightly negative effect for
a header only module, by increasing verbosity, and hence increasing time
to read and understand the header.
 
Another such contextual disadvantage is that `const` prevents moving. If
a function stores an argument, or returns it, then it's desirable to be
able to move it. And this can make a huge difference.
 
For example, consider the following ¹contrived code to compute the
Collatz sequence recursively:
 
#include <vector>
#include <iostream>
#include <utility> // std::move
using namespace std;
 
auto is_odd( int const x ) -> bool { return x%2 == 1; }
 
auto concat( vector<int> v, int const x )
-> vector<int>
{
v.push_back( x );
return move( v );
}
 
auto collatz_aux( vector<int> numbers, int const n )
-> vector<int>
{
return (false? vector<int>{}
: n == 1? concat( move( numbers ), 1 )
: is_odd( n )? collatz_aux( concat( move( numbers ), n ),
3*n + 1 )
: collatz_aux( concat( move( numbers ), n ),
n/2 )
);
}
 
auto collatz( int const n )
-> vector<int>
{ return collatz_aux( {}, n ); }
 
auto main()
-> int
{
for( int const x : collatz( 42 ) )
{
cout << x << ' ';
}
cout << endl;
}
 
As given this has O(n) complexity, where n is the length of the final
sequence.
 
Change the `number` formal argument to `const`, and you prevent moving,
thus changing the /behavior/ to O(n^2) complexity.
 
That's not just some constant factor of inefficiency due to some extra
copying of data, it's one level up in the orders of inefficiency,
quadratic time. Of course, the compiler may still optimize that away.
But it would not be proper to rely on the compiler to figure that out.
 
So as a rule, where an argument is returned, or modified and returned,
as above, or copied to storage persisting beyond the function call, it's
generally a good idea to leave out the `const`.
 
But especially when the argument is returned without being modified
there is a conflict between these two ideals: being able to easily
reason about the effect and correctness of the code due to guaranteed
immutability of the argument, its `const`-ness, and supporting
efficiency, which requires some final pilfering of resources from the
argument, and hence that the argument is non-`const`.
 
 
Cheers & hth.,
 
- Alf
 
Notes:
¹ I'm indebted to Andrew Koenig for the Collatz example above, because I
invented it in response to an article he wrote about list-based
recursion, with a Collatz example, in Dr. Dobbs Journal.
Adam Badura <adam.f.badura@gmail.com>: Jun 11 11:49PM -0700


> void foo( int const x ) { gurgle_snap( x ); cout << x << endl; }
 
> … which
 
> • is an implementation of the former declaration,
 
Just to make it more clear - as I understand that when you can (declaration split from definition) you skip the const on declaration and have it on definition only? Or for the consistency you have it always?
 
For me the fact that const on argument is unimportant to the type was always strongly discouraging. However now when I think about it I'm unable to justify this to myself anymore.
David Brown <david.brown@hesbynett.no>: Jun 12 09:04AM +0200

(Please use a real newsreader and a real newsserver, not Google groups -
it makes the formatting and line wrapping much nicer.)
 
On 10/06/17 22:48, Adam Badura wrote:
 
> First issue is that now we no longer have compilation error for
> missing value. At best we will get a warning. Not so bad, but I would
> prefer a required error rather then optional warning.
 
If you are OK with gcc specific features, you can use:
 
#pragma GCC diagnostic push
#pragma GCC diagnostic error "-Werror=switch"
 
constexpr inline char const* enum_value_to_string(color v)
{ ... }
 
#pragma GCC diagnostic pop
 
 
> size of the string. sizeof(enum_value_name<color, color::black>) is
> expected 13. While with enum_value_to_string function I'm left with
> calling std::strlen.
 
You have to use strlen, but gcc will calculate it at compile time, so at
least the generated code should be optimal.
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Jun 12 09:50AM +0200

On 12-Jun-17 8:49 AM, Adam Badura wrote:
> (declaration split from definition) you skip the const on declaration
> and have it on definition only? Or for the consistency you have it
> always?
 
My personal preference is to have top level `const`-s on definition
only, because that's where they have an advantage, while in the pure
declaration they're negative value noise.
 
 
> For me the fact that const on argument is unimportant to the type was
> always strongly discouraging. However now when I think about it I'm
> unable to justify this to myself anymore.
 
:)
 
 
Cheers,
 
- Alf
Adam Badura <adam.f.badura@gmail.com>: Jun 12 01:25AM -0700


> constexpr inline char const* enum_value_to_string(color v)
> { ... }
 
> #pragma GCC diagnostic pop
 
A warning that is normally issued by GCC (and likely many if not most other compilers) is typically enough IMHO. Yet still vendor-agnostic error instead of it would be better.
 
But the warning alone is why I prefer the switch approach I showed here over array-based approaches as proposed here by Alf P. Steinbach. switch also nicely deals with enum numeric values that are not continuous starting from zero (or close enough). While I believe that if the values are such the compiler can still optimize switch into array.
 
> > calling std::strlen.
 
> You have to use strlen, but gcc will calculate it at compile time, so at
> least the generated code should be optimal.
 
I didn't know about it. Nice! How can you be sure of this?
David Brown <david.brown@hesbynett.no>: Jun 12 11:16AM +0200

On 12/06/17 10:25, Adam Badura wrote:
 
> A warning that is normally issued by GCC (and likely many if not
> most other compilers) is typically enough IMHO. Yet still vendor-agnostic
> error instead of it would be better.
 
Sure, I agree here. Maybe something helpful will eventually make it
into the C++ standards as a [[ ]] attribute. But at the moment, the gcc
pragma is the best available.
 
> switch also nicely deals with enum numeric values that are not
> continuous starting from zero (or close enough). While I believe that if
> the values are such the compiler can still optimize switch into array.
 
Yes, that's the compiler's job. gcc is good at optimising switches in a
variety of ways.
 
 
>> You have to use strlen, but gcc will calculate it at compile time, so at
>> least the generated code should be optimal.
 
> I didn't know about it. Nice! How can you be sure of this?
 
Try it and see. The compiler knows how functions like strlen and strcat
work, and optimises based on that - including pre-calculating the results.
 
But the details can vary according to compiler switches, and perhaps
also in how the functions are used - test it a little before relying on it.
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: