Sunday, April 26, 2015

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

Ian Collins <ian-news@hotmail.com>: Apr 19 04:52PM +1200

Stefan Ram wrote:
 
> What is this? { 1, 2, 3 } seems to be used to initialize a
> temporary object whose lifetimes ends at the semicolon, so
> the pointer y then would be dangling?
 
It's an initialiser list. To quote cplusplus.com:
 
"initializer_list objects are automatically constructed as if an array
of elements of type T was allocated, with each of the elements in the
list being copy-initialized to its corresponding element in the array,
using any necessary non-narrowing implicit conversions."
 
So while the object is a temporary, the data it references is not. Note
that the return type of std::begin() is a const T* (constexpr in C++14).
 
--
Ian Collins
Ian Collins <ian-news@hotmail.com>: Apr 20 07:52PM +1200

Paavo Helde wrote:
> other temporary object [...]"
 
> So, as the array is temporary, a pointer to its element can and will
> become dangling as far as I can see.
 
I thought the clarification (making the return value a constexpr) takes
care of that. Certainly the generated code I've checked for a couple of
compilers shows the values being accessed from static data. For example
gcc -O3 -std=c++11 (or -O3 -std=c++14) compiles
 
 
int c();
 
int f()
{
const int* y = std::begin({ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 });
 
return y[c()];
}
 
as
 
_Z1fv:
pushl %ebp
movl %esp, %ebp
subl $8, %esp
call _Z1cv
movl ._0(,%eax,4), %eax
leave
ret
 
where ._0 is
._0:
.long 1
.long 2
.long 3
.long 4
.long 5
.long 6
.long 7
.long 8
.long 9
.long 10
 
and
 
int f()
{
const int* y = std::begin({ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 });
 
return y[4];
}
 
as
 
_Z1fv:
movl $5, %eax
ret
 
:)
 
--
Ian Collins
ram@zedat.fu-berlin.de (Stefan Ram): Apr 20 10:24PM

>Which methods (copy constructor, copy assignment operator,....)
>must Carp and Tuna implement for the std::copy function to work
>properly (to perform a deep copy on my vector)?
 
If you want to use the "algorithm" "::std::copy", then it
seems that you need to use a custom "smart pointer" class
for your objects that deep-copies it pointees when copied.
 
The following code shows a deep copy of a vector of pointers
/without/ ::std::copy (not fully tested).
 
#include <iostream>
#include <ostream>
#include <memory>
#include <vector>
 
struct Fish
{ virtual void print() = 0;
virtual ::std::unique_ptr< Fish >clone() = 0; };
 
class Tuna : public Fish
{ void print () override { puts( "Tuna" ); }
::std::unique_ptr< Fish >clone () override
{ return ::std::make_unique< Tuna >( *this ); }};
 
class Carp : public Fish
{ void print () override { puts( "Carp" ); }
::std::unique_ptr< Fish >clone () override
{ return ::std::make_unique< Carp >( *this ); }};
 
int main()
{ ::std::vector< ::std::unique_ptr< Fish >> v;
v.push_back( ::std::make_unique< Tuna >() );
v.push_back( ::std::make_unique< Carp >() );
::std::vector< ::std::unique_ptr< Fish >> w;
for( auto & f: v )w.push_back( f->clone() ); /* copying is here */
for( auto & f: w )f->print(); }
ram@zedat.fu-berlin.de (Stefan Ram): Apr 23 10:36PM

People told me that
 
::std::string s( ... )
 
was »direct initialization« and
 
::std::string s = ...
 
was »copy initialization«.
 
Herb Sutter wrote »Copy initialization means the object is
initialized using the copy constructor«.
 
I believe that in the case
 
::std::string t;
::std::string s( t );
 
, the object »s« is initialized using the copy constructor.
So then this is copy initialization, even if it uses
parentheses?
ram@zedat.fu-berlin.de (Stefan Ram): Apr 20 12:45AM

>On 4/19/2015 7:30 PM, Stefan Ram wrote:
>>Can one define a function only in the case that a function
>>is not declared?
...
>What problem are you trying to solve?
 
I want to write my code (e.g. for my tutorial) already in
the C++14 style, e.g., using »::std::make_unique« instead
of »::std::unique( new ...«.
 
Some implementations do not already supply »make_unique«,
so I thought about adding some lines at the top that define
»make_unique« if it's not declared at this point.
ram@zedat.fu-berlin.de (Stefan Ram): Apr 20 04:55PM

>(according to www.cplusplus.com & www.cppreference.com):
>void open (const char* filename, ios_base::openmode mode = ios_base::in);
>void open (const string& filename, ios_base::openmode mode = ios_base::in);
 
This is called a »declaration« or part of what is called a
»synopsis«.
 
>Why isn't the open member function that takes one parameter
>part of the www.cplusplus.com std::ifstream::open definition?
 
It /is/ there. Because the second parameter is declared with
a default value, it can be omitted.
 
It might help you to read a good textbook, such as »The C++
programming language, fourth edition« by Bjarne Stroustrup.
ram@zedat.fu-berlin.de (Stefan Ram): Apr 19 11:30PM

Can one define a function only in the case that a function
is not declared?
 
For example, define »make_unique« at the top of a
translation unit with lines that only have this effect
when make_unique is not already declared at this point?
ram@zedat.fu-berlin.de (Stefan Ram): Apr 21 05:12AM

>Stefan Ram wrote:
>18.9.3 Initializer list range access
>template<class E> const E* begin(initializer_list<E> il) noexcept;
 
I was not aware of this! Today it is specified as:
 
template<class E> constexpr const E* begin(initializer_list<E> il) noexcept;
Returns: il.begin().
 
. This copies the argument initializer list to the parameter il,
but if the underlying array has static storage duration,
then the pointer will /not/ dangle, indeed.
ram@zedat.fu-berlin.de (Stefan Ram): Apr 21 04:43PM

>If it's better clearly depends on the real application. unique_ptr's are
>inadequate, if you need to copy the vector for some reasons.
 
I just posted code in
 
<deep-copy-20150421001620@ram.dialup.fu-berlin.de>
 
that uses make_unique /and/ copies the vector.
 
Also, it is written in
 
herbsutter.com/2013/05/29/gotw-89-solution-smart-pointers/
 
»When in doubt, prefer unique_ptr by default, and you can
always later move-convert to shared_ptr if you need it.«
ram@zedat.fu-berlin.de (Stefan Ram): Apr 21 03:13AM

>>So, as the array is temporary, a pointer to its element can and will
>>become dangling as far as I can see.
>I thought the clarification (making the return value a constexpr) takes
 
»constexpr« did not occur so far. A const& can extend the
lifetime of a temporary, but it must be bound to it directly,
not via a pointer.
 
»::std::begin« does not accept an initialization list, only
an array reference, so a temporary array will be created and
the begin pointer of that array will be computed. The result
is a pointer to the begin of that array. Then, that array will
be destroyed. It is as if
 
#include <initializer_list>
#include <iostream>
#include <ostream>
 
struct array
{ array( ::std::initializer_list< int >const ){};
~array(){ ::std::cout << "I, temporary array, destroyed\n"; } };
 
int * begin( array ){ return nullptr; }
 
int main()
{ ::std::cout << "before\n";
const int * y = begin( { 1, 2, 3 }); /* this is like your code */
::std::cout << "after\n";
::std::cout << "y = " << y << '\n'; }
 
before
I, temporary array, destroyed
after
y = 0
 
> Certainly the generated code I've checked for a couple of
>compilers shows the values being accessed from static data.
 
When arguing about C++, the language, C++s, the implementations,
are not authoritative. Or, as Bartosz Milewski puts it:
»The fact that the program works has no relevance.«
ram@zedat.fu-berlin.de (Stefan Ram): Apr 21 01:36AM

> virtual ::std::unique_ptr< Fish >clone() = 0; };
>class Tuna : public Fish
>{ void print () override { puts( "Tuna" ); }
...
>for( auto & f: w )f->print(); }
 
I only now become aware of the fact that the
»print« method of »Tuna« is called by the client,
even though it is »privat« in »class Tuna«!
Or does it »inherit« the »public«?
 
I wanted to make »print« public, but forgot to
make it public in »class Tuna«.
 
Is this good or bad style?
Marcel Mueller <news.5.maazl@spamgourmet.org>: Apr 23 09:53PM +0200

On 23.04.15 21.34, Doug Mika wrote:
> #include <iostream>
> #include <vector>
> #include <algorithm>
[...]
> My question is, I DID NOT include <iterator> library, what distance() function am I using in this piece of code?
 
The standard library headers are allowed to include each other. So the
<iterator> include might be included indirectly by one of the others,
e.g. <algorithm>.
 
Of course, no program should rely on that - in fact many do so.
 
 
Marcel
Juha Nieminen <nospam@thanks.invalid>: Apr 20 02:30PM

> int a[] = {1, 2};
> auto n = end(a) - begin(a);
> }
 
Here 'a' is a static array, not a pointer. Thus std::begin() and std::end()
work fine with it.
 
> {
> auto n = end(a) - begin(a);
> }
 
Here 'a' is a pointer, not a static array, thus they don't work with it.
 
The syntax you used doesn't mean "static array". It means "pointer".
To receive a static array as parameter you have to use a different
syntax:
 
void testBeginEnd(int (&a)[2])
 
(Although note that the entire array is not passed to the function,
but rather a reference to the original array.)
 
--- news://freenews.netfront.net/ - complaints: news@netfront.net ---
Victor Bazarov <v.bazarov@comcast.invalid>: Apr 20 10:45AM -0400

On 4/20/2015 10:30 AM, Juha Nieminen wrote:
 
> void testBeginEnd(int (&a)[2])
 
> (Although note that the entire array is not passed to the function,
> but rather a reference to the original array.)
 
Just a nit-pick... Neither in the former example, nor in the latter
declaration, the array is *static*. While severely overloaded, the term
'static' has nonetheless specific meaning that doesn't apply here, I think.
 
It is better to use the term "an array of a known dimension" instead of
"static array" in such explanations. In a declaration "foo(int a[])"
the argument is "an array of unknown dimension", which inturnally (a pun
on "in turn", he-he) is converted into a pointer, as you already pointed
out.
 
V
--
I do not respond to top-posted replies, please don't ask
Victor Bazarov <v.bazarov@comcast.invalid>: Apr 20 09:03AM -0400

On 4/20/2015 4:44 AM, peter koch wrote:
 
> int i = 3.14;
> int i = { 3.14 };
 
> The first one succeeds, where the second one gives a compiler error.
 
I am not sure why you have combined the two forms in the latter
statement and expect it to work. Shouldn't the comparison have been
 
int i = 3.14;
 
with
 
int i{3.14};
 
?
 
V
--
I do not respond to top-posted replies, please don't ask
Victor Bazarov <v.bazarov@comcast.invalid>: Apr 20 12:16PM -0400

On 4/20/2015 11:55 AM, Doug Mika wrote:
> Does this mean I could write:
> cin = cin.get(someString,255);
> What purpose does this return type serve?
 
The purpose is to allow chaining of function calls, like
 
cin.get(blah).get(blahblah)
 
or using it in an expression
 
cin.get(blah) >> somethingelse;
 
V
--
I do not respond to top-posted replies, please don't ask
legalize+jeeves@mail.xmission.com (Richard): Apr 19 05:13PM

[Please do not mail me a copy of your followup]
 
Having interviewed many people over the past few years, I'd prefer someone
who knew test-driven development and agile development practices over
someone who knew how to answer "brain teaser" questions anyday.
Knowing how to write testable code, how to perform incremental design,
how to refactor a working system are the day-to-day skills I use all
the time and those I seek to find in someone I'm adding to my team.
 
We moved to giving people a programming problem over interviewing them
because we wasted so much time interviewing people who weren't that
good. The response to our programming problem was much more
informative than any amount of Q&A style interviewing. If they did a
decent job on the problem, then I'd prefer pair programming with the
candidate over any Q&A style interview.
 
I think I *might* have browsed the book mentioned by the OP in the
bookstore. If it's the one I remember, the emphasis was all wrong for
the skills needed on a modern agile team. It was the kind of things
you needed to pass a Microsoft interview in the 90s or early 2000s,
but completely missed any of the skills that I want in a modern team
member.
 
YMMV.
 
For job seekers, this is my advice:
 
- Let yourself pick the job, instead of the job picking you. This
takes more time, but it is more satisfying for the applicant.
Research and identify the company that *you* want to work for and
approach them for a position, whether they have a posted job opening
or not. From the employers perspective this means they're talking
to someone who actively wants to work for them, instead of just
random applications they received because they had a job posting
open. Even if they say they have no positions open, ask to pair
with one of their teams for a day. Volunteer to sign an NDA if
they are concerned about exposing you to IP. If this doesn't result
in a job and you still are interested in this company, keep
contacting them every couple of months -- frequent enough to remind
them that you *want* to work for them, but not so frequently as to
be a pest. If this is a stable or growing company, eventually they
will have an opening either due to attrition or growth and you will
be top in their mind when they consider opening a position.
 
- Ask for your interview to be in the form of a pair programming
session. You'll both be working on code together in a manner that
more accurately reflects what it will be like to work there. You'll
get a better sense of how well you will fit into the team -- you
should switch pairs every hour or so, depending on the team size.
Modern software development is teamwork, not a solitary hermitic
experience in a cave. Given the choice between a regular
programmer that fits well in the team and an abrasive "rock star",
I'd take the former. A team goes faster when everyone on it gets
along well with each other. This form of interview takes longer,
but it gives the applicant a chance to get over "interview jitters"
and relax, focusing on solving problems together with code.
 
- Interview the employer, instead of them interviewing you. This will
happen in an unforced natural way as a consequence of the above two
items, but if you're in a standard Q&A verbal or in-person interview,
come prepared with a list of questions for your prospective team
that you want answered. This changes your perceived attitude as an
applicant from "I just want to get paid to program and I hope they
hire me" to one who is actively seeking an employer and team that
provides the satisfaction you want. If it's not a good fit, it's
best for both sides to learn this in the interview than it is to
find this out after 6 months of working there.
 
- Make significant contributions to an open source project. This will
give you a public portfolio of code that you can share with
potential employers. Contribute in such a way that the employer can
not only browse your code, but also the commit history. Github is
excellent for this, but there are others that are just as well.
 
- An alternative to contributing to open source is to work problems on
exercism.io and share links to your solutions. Employers will be
able to see your solution to a variety of problems, see iterations
on your solutions and see what kind of feedback you obtained from
others on your solutions. This isn't as good as doing actual
features on an open source application, but its better than nothing.
 
The above suggestions are from the perspective of "I have time to look
for a satisfying and rewarding job". If you're in the situation of
having immediate financial needs that can't wait, then the above
approach may take too long for you. However, you can still use some
elements of the above to make your interviewing process go smoother.
In particular, contributing to open source or working problems in
exercism.io helps you build a public code portfolio and that always
helps more than phrasing on a resume. Even if you have immediate need
for employment, this is something you can do right away to help
yourself out. If you're currently unemployed, then this should be
your full-time job until you are employed.
--
"The Direct3D Graphics Pipeline" free book <http://tinyurl.com/d3d-pipeline>
The Computer Graphics Museum <http://computergraphicsmuseum.org>
The Terminals Wiki <http://terminals.classiccmp.org>
Legalize Adulthood! (my blog) <http://legalizeadulthood.wordpress.com>
Melzzzzz <mel@zzzzz.com>: Apr 21 04:23AM +0200

On 21 Apr 2015 01:36:10 GMT
 
> I wanted to make »print« public, but forgot to
> make it public in »class Tuna«.
 
> Is this good or bad style?
 
Well, one can't call print on Tuna but can on Fish.
I remember it was considered to be good style to make virtual functions
private and call them from base class non virtual functions eg:
 
class Base {
public:
void f() {
virt();
}
}
private:
virtual void virt()=0;
};
 
class Derived : public Base {
void virt() {}
};
 
Derived d; d.f();
Luca Risolia <luca.risolia@linux-projects.org>: Apr 21 01:06AM +0200

Il 20/04/2015 23:28, Paavo Helde ha scritto:
> vector<std::shared_ptr<Fish>> vecOfFish;
> vecOfFish.push_back(std::shared_ptr<Fish>(new Tuna()));
> vecOfFish.push_back(std::shared_ptr<Fish>(new Carp()));
 
Use std::make_shared() whenever possible. It's more efficient and more
compact (in terms of both object and source code).
 
In this case:
vecOfFish.push_back(std::make_shared<Tuna>());
vecOfFish.push_back(std::make_shared<Carp>());
Luca Risolia <luca.risolia@linux-projects.org>: Apr 21 08:22PM +0200

Il 21/04/2015 06:03, Victor Bazarov ha scritto:
 
> Given 'class Derived : public Base {};', is 'shared_ptr<Derived>'
> convertible to 'shared_ptr<Base>'?
 
Yes, although they are not covariant.
Victor Bazarov <v.bazarov@comcast.invalid>: Apr 20 12:52PM -0400

On 4/20/2015 12:35 PM, Doug Mika wrote:
 
> ifstream inFile;
> inFile.open("input.dat");
 
> Why isn't the open member function that takes one parameter part of the www.cplusplus.com std::ifstream::open definition?
 
Read up on default argument values.
 
V
--
I do not respond to top-posted replies, please don't ask
Victor Bazarov <v.bazarov@comcast.invalid>: Apr 19 08:36PM -0400

On 4/19/2015 7:30 PM, Stefan Ram wrote:
 
> For example, define »make_unique« at the top of a
> translation unit with lines that only have this effect
> when make_unique is not already declared at this point?
 
There is probably a way to do it using SFINAE, by trying to take the
address of that function. If the function is not declared, taking the
address of it should be not possible, so the template is not going to be
generated... Then you could try to define your function as the member
of that template, or specialize it... Seems like a lot of work for no
obvious gain, though.
 
What problem are you trying to solve?
 
V
--
I do not respond to top-posted replies, please don't ask
Louis Krupp <lkrupp@nospam.pssw.com.invalid>: Apr 19 07:56PM -0600

On 19 Apr 2015 23:30:54 GMT, ram@zedat.fu-berlin.de (Stefan Ram)
wrote:
 
 
> For example, define »make_unique« at the top of a
> translation unit with lines that only have this effect
> when make_unique is not already declared at this point?
 
If you can depend on only C++14 implementations having make_unique,
then this page might be useful:
 
http://sourceforge.net/p/predef/wiki/Standards/
 
Louis
peter koch <peter.koch.larsen@gmail.com>: Apr 26 04:34PM -0700

lørdag den 25. april 2015 kl. 20.29.02 UTC+2 skrev Paul:
 
> Why is writing through p undefined? I thought this was an archetypal use of const_cast -- create a non-const object from a low-level const object.
 
> Why is this use of const_cast wrong?
 
> Paul
 
You can not modify a const object. So if you are to modify p you need to be sure that pc - despite the declaration - points to non-constant data.
One use of const_cast is to implement non-const member functions via the const function. Another use is to cast to const, and finally you may use const_cast - carefully - when interfacing to legacy code that is not const aware.
Ian Collins <ian-news@hotmail.com>: Apr 27 11:32AM +1200


> http://stackoverflow.com/questions/29882666/c-socket-programming-read-write
 
> Is limiting the size of the read the problem as EJP suggests?
> I was thinking it might have to do with the OP's assuming int is 4 bytes.
 
I often wonder why people compile scungy C as C++...
 
There are a number of possible mistakes in the code, assuming the file
size will fit in an int would be more of a problem than assuming
sizeof(int).
 
--
Ian Collins
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: