Wednesday, January 25, 2017

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

Christiano <christiano@engineer.com>: Jan 25 11:29AM -0800

I come from the C language, see the following example:
 
// {======= get.c ============
#include <stdio.h>
 
int main(void)
{
char c;
char d;
 
c = getchar();
d = getchar();
 
putchar(c);
 
printf("\n");
 
putchar(d);
 
printf("\n");
 
 
return 0;
}
// }======= end get.c ========
 
Running (comments using notation ## comments ##):
debian@debian:~/principles$ gcc get.c -o get
debian@debian:~/principles$ ./get
##First I press Ctrl+D##
##Ctrl+D again##


debian@debian:~/principles$
 
That is, the two getchar tried to read the stdin and I pressed Ctrl + D to not feed the empty stdin.
Ok, Let's see something equivalent in C ++.
 
// {=========== get++.cpp ===========
#include <iostream>
using namespace std;
 
int main(void)
{
char c;
char v;
 
cin >> c;
cin >> v;
 
cout << c;
 
cout << endl;
 
cout << v;
 
cout << endl;
 
return 0;
}
// }=========== end get++.cpp ======
 
There is a difference in behavior here.
Running (comments using notation ## comments ##):
debian@debian:~/principles$ g++ get++.cpp -o get++
debian@debian:~/principles$ ./get++
##I press Ctrl+D just one time##

@
debian@debian:~/principles$
 
That is, the first crash of cin was enough to fail the second without giving me the chance to fill the stdin in the second time.
I just pressed Ctrl + D once and that was enough for cin >> v to fail.
 
Now, I will show a code based from book "Programming: Principles and Practice Using C++ Second Edition":
// {========= tdx.cpp ===========
#include "std_lib_facilities.h"
 
double some_function()
{
double d = 0;
cin >> d;
if(!cin)
error("Couldn't read a double in some_function()");
 
return d;
}
 
int main(void)
try {
double x = some_function();
cout << "The value read is: " << x << endl;
return 0;
}
catch(runtime_error &e) {
cerr << "runtime error: " << e.what() << "\n";
keep_window_open();
 
return 1;
}
// } ======= end tdx.cpp ========
 
Where std_lib_facilities.h is:
http://www.stroustrup.com/Programming/PPP2code/std_lib_facilities.h
 
Running (comments using notation ## comments ##):
 
debian@debian:~/principles$ g++ tdx.cpp -o tdx
debian@debian:~/principles$ ./tdx
| ##the cin >> d wants a double, i will give "|" to force the fail##
runtime error: Couldn't read a double in some_function()
Please enter a character to exit
##Here he passed straight through without pausing.##
debian@debian:~/principles$
 
The program is designed to "pause" when the "double type" reading fails, before exiting.
But this is not what happens, as you can see.
Looking inside std_lib_facilities.h, you can see what keep_window_open () is:
inline void keep_window_open()
{
cin.clear();
cout << "Please enter a character to exit\n";
char ch;
cin >> ch;
return;
}
 
That is, "the first crash of cin was enough to fail the second without giving me the chance to fill the stdin in the second time." Again.
 
My question is: Is this a book error? Is this behavior normal?
 
I've scanned the pages, here:
http://imgur.com/a/8GEkE
http://imgur.com/a/dNWGe
Bo Persson <bop@gmb.dk>: Jan 25 08:44PM +0100

On 2017-01-25 20:29, Christiano wrote:
> debian@debian:~/principles$
 
> That is, the first crash of cin was enough to fail the second without giving me the chance to fill the stdin in the second time.
> I just pressed Ctrl + D once and that was enough for cin >> v to fail.
 
This is by design. cin will remember the failure to read and will not
attempt to read anything more, until you call cin.clear() to clear the
error state.
 
 
Bo Persson
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Jan 25 09:05PM +0100

On 25.01.2017 20:29, Christiano wrote:
> �
> �
> debian@debian:~/principles$
 
Yep, the C FILE* streams do not have EOF as a state, they just report
EOF when they read in zero bytes – which is what happens when you press
Ctrl+D without having typed anything on the line, there is nothing, so
the read returns an empty sequence of bytes.
 
At one time long ago this was used in a "readslow" program to follow the
thinking of a famous chess program.
 
Wait let me google that. OK found something about it, not the chess
tournament thing, but it was mentioned in the old classic "The UNIX
Programming Environment" by Kernighan & Pike:
 
 
[TUPE]
> costly in CPU time. Thus this version of readslow copies its input up to the
> end of file, sleeps a while, then tries again. If more data arrives while it is
> asleep, it will be read by the next read.
[/TUPE]
 
Continuing with your posting:
 
On 25.01.2017 20:29, Christiano wrote:
> }
> // }=========== end get++.cpp ======
 
> There is a difference in behavior here.
 
Yes, them dang iostreams are /stateful/. Once a stream gets into an
error state, which is a kind of "ignore all attempted operations" mode,
you have to clear it in order to continue.
 
In passing, `f(void)` is a C-ism. In C the `void` there ensures that the
function is declared as taking no arguments, as opposed to an arbitrary
number of arguments with just `f()`. But in C++ `f()` says directly that
it takes no arguments, there's no need for `f(void)`.
 
 
> }
 
> That is, "the first crash of cin was enough to fail the second without giving me the chance to fill the stdin in the second time." Again.
 
> My question is: Is this a book error?
 
Yes. But it's a different issue. The `keep_window_open` function does
clear the stream error state, via a call to `clear`. But it fails to
empty the input buffer, where characters from the failed read still
linger. It could empty the input buffer with a call to `ignore`.
 
Check whether this bug is already in the book's errata list. If it isn't
then report it to Bjarne.
 
 
> Is this behavior normal?
 
Yes, it's by design.
 
But note that the `keep_window_open` issue is not the same as the end of
file state you encountered earlier.
 
For the first issue, about EOF, try out the following program:
 
#include <iostream>
#include <string>
using namespace std;
 
auto main()
-> int
{
double x;
cout << "? "; cin >> x;
if( cin.fail() )
{
cout << "Failed. This was left in input buffer: `";
cin.clear();
string s; getline( cin, s );
cout << s << "`." << endl;
}
else
{
cout << "Oh, the number " << x << "! Thanks! :)" << endl;
}
}
 
 
> I've scanned the pages, here:
> http://imgur.com/a/8GEkE
> http://imgur.com/a/dNWGe
 
 
Cheers & hth.,
 
- Alf
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Jan 25 09:08PM +0100

On 25.01.2017 21:05, Alf P. Steinbach wrote:
> For the first issue, about EOF, try out the following program:
 
I meant, for the second issue, about a failed read op. Grr.
 
Sorry 'bout that,
 
- Alf
Jorgen Grahn <grahn+nntp@snipabacken.se>: Jan 25 10:30PM

On Wed, 2017-01-25, Christiano wrote:
...
> ???
> ???
> debian@debian:~/principles$
 
You're describing feeding a process EOF on stdin more than once.
Can you see any practical use for this?
 
I have noticed the behavior, but I decided it has no practical use,
and that a program is better off honoring the EOF. Especially since
the behavior is limited to interactive use.
 
/Jorgen
 
--
// Jorgen Grahn <grahn@ Oo o. . .
\X/ snipabacken.se> O o .
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Jan 26 12:02AM +0100

On 25.01.2017 23:30, Jorgen Grahn wrote:
 
> You're describing feeding a process EOF on stdin more than once.
> Can you see any practical use for this?
 
> I have noticed the behavior, but I decided it has no practical use,
 
That may well be the case today. It wasn't always so. It was used.
 
 
> and that a program is better off honoring the EOF. Especially since
> the behavior is limited to interactive use.
 
Well, that's incorrect.
 
You can read more about it in my reply to the OP, earlier.
 
 
Cheers & hth.,
 
- Alf
"Christopher J. Pisz" <cpisz@austin.rr.com>: Jan 25 07:45AM -0600

I am trying to try out std::async and futures
 
In order to do this, I need to bind a class method I would like run
async. The class method in question has overloads. One version is the
top level, another is the recursive portion. etc.
 
What is the bind syntax?
 
It usually has worked fine for me with
std::bind(&MyClass::MyMethod, this, std::placeholders::_1);
but now I am dealing with an overloaded method with multiple arguments.
 
I am trying and failing with:
 
//------------------------------------------------------------------------------
MyThing::Permutations MyThing::GetPermutations() const
{
std::vector<std::future<Permutations> > futures;
auto func = std::bind<MyThing::Permutations(size_t,
size_t)>(&MyThing::GetPermutations, this, std::placeholders::_1,
std::placeholders::_2);
 
/*
for( size_t x = 0; x < m_numColumns; ++x )
{
for( size_t y = 0; y < m_numRows; ++y )
{
std::async(std::launch::async, &Board::GetPermutations,
this, x, y);
}
}
*/
GetPermutations(0, 0);
}
 
with a class that looks like:
 
//------------------------------------------------------------------------------
class MyThing
{
public:
 
typedef std::vector<std::string> Permutations;
 
MyThing();
~MyThing();
 
Permutations GetPermutations() const;
 
protected:
 
typedef std::vector<std::vector<bool> > UsedMap;
 
Permutations GetPermutations(size_t startingCoordinates_X
, size_t startingCoordinates_Y) const;
 
Permutations GetPermutations(size_t startingCoordinates_X
, size_t startingCoordinates_Y
, UsedMap usedMap) const;
 
};
"Christopher J. Pisz" <cpisz@austin.rr.com>: Jan 25 08:12AM -0600

On 1/25/2017 7:45 AM, Christopher J. Pisz wrote:
> , size_t startingCoordinates_Y
> , UsedMap usedMap) const;
 
> };
 
 
I got it. Twas the const keyword that was missing it seems.
 
auto func =
std::bind(static_cast<MyThing::Permutations(MyThing::*)(size_t, size_t)
const>(&MyThing::GetPermutations), this, std::placeholders::_2);
Chris Vine <chris@cvine--nospam--.freeserve.co.uk>: Jan 25 08:19PM

On Wed, 25 Jan 2017 08:12:35 -0600
> std::bind(static_cast<MyThing::Permutations(MyThing::*)(size_t,
> size_t)
> const>(&MyThing::GetPermutations), this, std::placeholders::_2);
 
You disambiguate overloads with static_cast. That was the bit that
made it work for you (unless your original version contained a typing
error so the static_cast was in your real code but omitted from your
posting by mistake). This did of course also require you to get the
signature right, which you did in your second version.
 
Chris
ram@zedat.fu-berlin.de (Stefan Ram): Jan 24 11:56PM

>So this must be an error in PPP2 (principles and practices
>programming using c ++ second edition).
>See the page 149:
 
I don't watch pictures from web sites, but I don't
believe that you represented the title of the book
correctly, and I don't believe that a book co-authored
by Bjarne Stroustrup contains such a blatand mistake.
ram@zedat.fu-berlin.de (Stefan Ram): Jan 25 12:12AM

>remember any consensus being reached. But it's worth noting that with
>most compilers, with proper tool usage you can do this also with simple
>`[i]` indexing, possibly with crash response instead of exception.
 
The following is one of the programs written by Bjarne
Stroustrup that I like the most.
 
Bjarne Stroustrup himself writes about this program:
»I often use a simple range-checking adaptation of vector:«.
 
That is, it is something he himself uses often.
 
template<typename T>
class Vec : public std::vector<T> {
public:
using vector<T>::vector;
T& operator[](int i)
{ return vector<T>::at(i); }
const T& operator[](int i) const
{ return vector<T>::at(i); }
};
 
(And I only now have become aware of that the way that he
uses the braces in the method declarations of this program
seems to be the way I use them:
 
»{« at the start of a line, followed by a space,
»}« at the end of a line, preceded by a space.)
ram@zedat.fu-berlin.de (Stefan Ram): Jan 25 07:50PM

>That is, the first crash of cin was enough to fail the second
>without giving me the chance to fill the stdin in the second
>time.
 
I don't know whether this is your problem, but you
can clear some failbits (or such) using
 
::std::cin.clear();
 
, and sometimes it also helps to clear the current line from
the input buffer
 
::std::cin.ignore
( ::std::numeric_limits< ::std::streamsize >::max(), '\n' );
 
. Some relevant includes for this might be
 
#include <iostream>
#include <ostream>
#include <istream>
#include <limits>
 
.
woodbrian77@gmail.com: Jan 25 09:58AM -0800

I'd like to see something like this added to std::exception
and types derived from it:
 
virtual ::std::string_view what_view () const noexcept;
 
In this file:
 
https://github.com/Ebenezer-group/onwards/blob/master/cmwAmbassador.cc
 
there's some code like this:
 
}catch(::std::exception const& ex){
syslog_wrapper(LOG_ERR,"Mediate request: %s",ex.what());
middle_messages_front::Marshal(localsendbuf,false,ex.what());
}
 
I can't change the first call to "what" unless I find an alternative to
syslog. But I could change the second call to "what" to "what_view"
and avoid the need to recalculate the length of the string.
 
The proposed function could be implemented like this:
 
virtual ::std::string_view what_view () const noexcept
{ return std::string_view(whatStr); } // where whatStr is a std::string.
 
At least that's how I would do it here:
https://github.com/Ebenezer-group/onwards/blob/master/ErrorWords.hh
 
I'm not planning on going to the upcoming C++ standardization
meeting in Kona, Hawii, but if someone is, feel free to mention
this. Thanks.
 
 
Brian
Ebenezer Enterprises - In G-d we trust.
http://webEbenezer.net
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Jan 25 08:17PM +0100


> I can't change the first call to "what" unless I find an alternative to
> syslog. But I could change the second call to "what" to "what_view"
> and avoid the need to recalculate the length of the string.
 
If you create your own exception class you can provide a method that
returns a string view, to avoid copying of the string.
 
Think also about creating an exception instance from a string view.
 
One doesn't want conversion to `std::string` there because that can throw.
 
 
 
> I'm not planning on going to the upcoming C++ standardization
> meeting in Kona, Hawii, but if someone is, feel free to mention
> this. Thanks.
 
Just a side note: exceptions and strings have a circular dependency
relationship, which makes it difficult to implement it all in header
only modules.
 
 
Cheers!,
 
- Alf
Jeff-Relf.Me <@.>: Jan 25 12:44AM -0800

Christiano <christiano@engineer.com>: Jan 24 03:39PM -0800

On Tuesday, January 24, 2017 at 8:25:42 PM UTC-2, Öö Tiib wrote:
 
> Undefined behavior may be whatever. It may output "v[5]==0"
> or it may crash or it may conjure demons out of your nose.
> Generally we avoid writing code that contains undefined behaviors.
 
Hi, thank you. I have rewritten the code (at the end of this post) adding ".at" instead .[x]. Now it is working as expected:
debian@debian:~/principles$ ./a.out
1 2 3 4 5
v[0]==1
v[1]==2
v[2]==3
v[3]==4
v[4]==5
Ops, range error
debian@debian:~/principles$
 
So this must be an error in PPP2 (principles and practices programming using c ++ second edition).
See the page 149:
http://imgur.com/a/E9m6Q
 
/// my new code2
#include <iostream>
#include <vector>
#include <stdexcept>
using namespace std;
 
int main(void)
try
{
vector<int> v;
for(int x;cin>>x;)
v.push_back(x);
 
for(int i=0;i<=v.size();++i)
cout << "v[" << i << "]=="<<v.at(i)<<'\n';
 
}
catch(out_of_range)
{
cerr << "Ops, range error\n";
 
return 1;
}
catch(...)
{
cerr <<"Exception: something get wrong\n";
 
return 2;
}
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Jan 25 12:55AM +0100

On 25.01.2017 00:39, Christiano wrote:
 
> So this must be an error in PPP2 (principles and practices
> programming using c ++ second edition). See the page 149:
> http://imgur.com/a/E9m6Q
 
It's just a unclear language, in the sense of using /too few words/ to
explain something, so that the point flies by the casual reader like a
passenger jet high above: such a jet liner is usually not even noticed.
 
"[The subscript operation] can check (and the `vector` we are using does"
 
You need to read that five times, say, in order to get the word count up
to an appropriate level commensurate with its importance. ;-)
 
That said, the wording is misleading in that it indicates that a given
vector implementation will either have a bounds-checking `operator[]` or
not. More commonly this can be specified when you build your program,
and instead of throwing an exception, it might just terminate the
program. The options for turning on and off such checking vary greatly
between compilers; it's not specified by the Holy Standard.
 
At one time great debates raged here in clc++ about whether using `.at`
was a good idea in order to catch subscript range errors. I can't
remember any consensus being reached. But it's worth noting that with
most compilers, with proper tool usage you can do this also with simple
`[i]` indexing, possibly with crash response instead of exception.
 
Cheers & hth.,
 
- Alf
Christiano <christiano@engineer.com>: Jan 24 04:37PM -0800

Hi, Alf, Thank you, you made me remember that the author occultly uses a header:
http://www.stroustrup.com/Programming/PPP2code/std_lib_facilities.h
 
So I decided to investigate if he was doing a special vector version, as you said.
 
See this code section:
template< class T> struct Vector : public std::vector<T> {
using size_type = typename std::vector<T>::size_type;
 
#ifdef _MSC_VER
// microsoft doesn't yet support C++11 inheriting constructors
Vector() { }
explicit Vector(size_type n) :std::vector<T>(n) {}
Vector(size_type n, const T& v) :std::vector<T>(n,v) {}
template <class I>
Vector(I first, I last) : std::vector<T>(first, last) {}
Vector(initializer_list<T> list) : std::vector<T>(list) {}
#else
using std::vector<T>::vector; // inheriting constructor

No comments: