Friday, May 5, 2017

Digest for comp.lang.c++@googlegroups.com - 10 updates in 5 topics

legalize+jeeves@mail.xmission.com (Richard): May 05 09:41PM

[Please do not mail me a copy of your followup]
 
Ian Collins <ian-news@hotmail.com> spake the secret code
>> these through manual testing would have been prohibitively tedious and
>> exhausting.
 
>You use naked pointers, shocking! :)
 
The code base is 25 years old in some places. It depends on
commercial libraries that are 15+ years old.
 
There's nothing wrong with naked pointers per se. The problem is when
they are both used to express access as well as ownership. The C++
Core Guidelines Support Library uses the owner<> template to decorate
a pointer as expressing the concept of ownership:
<http://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#gslview-views>
 
"The "raw-pointer" notation (e.g. int*) is assumed to have
its most common meaning; that is, a pointer points to an object,
but does not own it. Owners should be converted to resource
handles (e.g., unique_ptr or vector<T>) or marked owner<T*>."
 
For this code base, it will be a while before I could use unique_ptr<>
because of the legacy build environment. Modernization is on the road
map, but has other organizational dependencies that aren't as easy to
fix as committing to the repository :).
 
For those of you who work in organizations larger than yourself, this
is probably a familiar story.
 
When I was at Fusion-io, we had the difficulty that we couldn't switch
to C++11 because the enterprise linux distributions didn't come with a
modern compiler by default. Yes, this was a solvable problem, but
involved company-wide concerns beyond our team and as a result, it
didn't move forward as rapidly as we would have liked. RHEL7 uses gcc
4.8.x by default and at the time I was there, I don't think it was
even that far along. <https://access.redhat.com/solutions/19458>
SUSE had a similar problem. I understand why they are laggy, but it
means you have to go out of your way on these linux distros to build
and redist applications using modern C++.
--
"The Direct3D Graphics Pipeline" free book <http://tinyurl.com/d3d-pipeline>
The Terminals Wiki <http://terminals-wiki.org>
The Computer Graphics Museum <http://computergraphicsmuseum.org>
Legalize Adulthood! (my blog) <http://legalizeadulthood.wordpress.com>
woodbrian77@gmail.com: May 04 08:00PM -0700

I agree with him ... https://arne-mertz.de/2017/03/smelly-pair-tuple/
 
Std::any doesn't smell good either.
 
 
Brian
Ebenezer Enterprises - In G-d we trust.
http://webEbenezer.net
Ian Collins <ian-news@hotmail.com>: May 06 08:25AM +1200

> I agree with him ... https://arne-mertz.de/2017/03/smelly-pair-tuple/
 
A poorly written article by someone who doesn't appear to understand
where and how tuples are used.
 
--
Ian
bitrex <bitrex@de.lete.earthlink.net>: May 05 01:34PM -0400

Is it OK to use the templated circular buffer included in Boost to store
std::shared_ptrs to dynamically allocated objects?
 
The documentation says "One recommend alternative is the use of smart
pointers [1]. (Any container of std::auto_ptr is considered particularly
hazardous. [2] )"; however it doesn't seem entirely clear on whether a
resource held by a smart pointer within the container instead of a
regular ol' pointer will be released correctly if a block in the buffer
is overwritten.
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: May 05 08:16PM +0200

On 05-May-17 7:34 PM, bitrex wrote:
> resource held by a smart pointer within the container instead of a
> regular ol' pointer will be released correctly if a block in the buffer
> is overwritten.
 
It's very very very rare that a container doesn't properly destroy its
items. That's only done for very low level things, like C `realloc`.
When it's done in any halfway quality softeware it's documented.
 
In other words, you can trust the Boost containers to do the Right Thing.
 
 
Cheers & hth.,
 
- Alf
bitrex <bitrex@de.lete.earthlink.net>: May 05 03:51PM -0400

On 05/05/2017 02:16 PM, Alf P. Steinbach wrote:
 
> In other words, you can trust the Boost containers to do the Right Thing.
 
> Cheers & hth.,
 
> - Alf
 
Thanks!
kushal bhattacharya <bhattacharya.kushal4@gmail.com>: May 04 11:31PM -0700

On Friday, May 5, 2017 at 1:37:36 AM UTC+5:30, Chris M. Thomasson wrote:
> visualize newer features. :^)
 
> Common now, try to give proper attributes wrt quoting others. Pretty Please?
 
> ;^o
 
exactly :-)
kushal bhattacharya <bhattacharya.kushal4@gmail.com>: May 05 12:30AM -0700

On Thursday, May 4, 2017 at 1:54:28 PM UTC+5:30, Bonita Montero wrote:
 
> It works only with compilers that support C++ with the class template
> deduction feature. This is only a convenience-feature. The resulting
> code is exactly the same.
 
thanks for this approach maam :)
Christiano <christiano@engineer.com>: May 04 11:23PM -0300

------- Introduction ---------------
 
The book "Programming: Principles and Practice using C++" [1] says on chapter 11:
 
"Terms such as hex and oct that are used to change the behavior of the stream are called manipulators."
 
An example:
 
#include <iostream>
using namespace std;
int main()
{
cout << hex << 1234 << endl;
 
return 0;
}
 
Manipulators change stream flags whose format is represented by the type fmtflags.
 
Here, we have a list with fmtflags:
 
basefield
oct
hex
dec
adjustfield
left
right
internal
floatfield
scientific
fixed
---------
boolalpha
showbase
showpoint
showpos
skipws
unitbuf
uppercase
 
from http://en.cppreference.com/w/cpp/io/ios_base/fmtflags
 
A combination of flags determines how the stream behaves, moreover, such a combination can be more easily and correctly altered by manipulators.
 
You can see the relationship between the flags and the behavior by looking at the following tables (from C++11 specification [3] : § 22.4.2.1.2 and §
22.4.2.2.2).
 
 
1. Input
 
1.1 Integers
+------------------------+------------------+
| State | stdio equivalent |
+------------------------+------------------+
| basefield == oct | %o |
| basefield == hex | %X |
| basefield == 0 | %i | [2]
| signed integral type | %d |
| unsigned integral type | %u |
+------------------------+------------------+
 
1.2 Floating point
 
For conversions to a floating type the specifier is %g.
 
2. Output
 
2.1 Integers
+--------------------------------------------+------------------+
| State | stdio equivalent |
+--------------------------------------------+------------------+
| basefield == oct | %o |
| (basefield == ios_base::hex) && !uppercase | %x | [2]
| (basefield == ios_base::hex) | %X |
| for a signed integral type | %d |
| for an unsigned integral type | %u |
+--------------------------------------------+------------------++
 
 
2.2 Floating point
 
+----------------------------------------------------------------------+------------------+
| State | stdio equivalent |
+----------------------------------------------------------------------+------------------+
| floatfield == ios_base::fixed | %f |
| floatfield == ios_base::scientific && !uppercase | %e |
| floatfield == ios_base::scientific | %E | [2]
| floatfield == (ios_base::fixed | ios_base::scientific) && !uppercase | %a |
| floatfield == (ios_base::fixed | ios_base::scientific) | %A |
| !uppercase | %g |
| otherwise | %G |
+----------------------------------------------------------------------+------------------+
 
And you can see the relationship between the manipulators and the flags by looking at the following table (from C++11 specification [3] : § 27.5.6).
 
+--------------+------------------------------------------------------------------------------+
| Manipulator | Effect |
+--------------+------------------------------------------------------------------------------+
| boolalpha | Calls str.setf(ios_base::boolalpha) |
| noboolalpha | Calls str.unsetf(ios_base::boolalpha) |
| showbase | Calls str.setf(ios_base::showbase) |
| noshowbase | Calls str.unsetf(ios_base::showbase) |
| showpoint | Calls str.setf(ios_base::showpoint) |
| noshowpoint | Calls str.unsetf(ios_base::showpoint) |
| showpos | Calls str.setf(ios_base::showpos) |
| noshowpos | Calls str.unsetf(ios_base::showpos) |
| skipws | Calls str.setf(ios_base::skipws) |
| noskipws | Calls str.unsetf(ios_base::skipws) |
| uppercase | Calls str.setf(ios_base::uppercase) |
| nouppercase | Calls str.unsetf(ios_base::uppercase) |
| unitbuf | Calls str.setf(ios_base::unitbuf) |
| nounitbuf | Calls str.unsetf(ios_base::unitbuf) |
| internal | Calls str.setf(ios_base::internal, ios_base::adjustfield) |
| left | Calls str.setf(ios_base::left, ios_base::adjustfield) |
| right | Calls str.setf(ios_base::right, ios_base::adjustfield) |
| dec | Calls str.setf(ios_base::dec, ios_base::basefield) |
| hex | Calls str.setf(ios_base::hex, ios_base::basefield) |
| oct | Calls str.setf(ios_base::oct, ios_base::basefield) |
| fixed | Calls str.setf(ios_base::fixed, ios_base::floatfield) |
| scientific | Calls str.setf(ios_base::scientific, ios_base::floatfield) |
| hexfloat | Calls str.setf(ios_base::fixed | ios_base::scientific, ios_base::floatfield) |
| defaultfloat | Calls str.unsetf(ios_base::floatfield) |
+--------------+------------------------------------------------------------------------------+
 
 
------- The "Problem" ---------------
 
The book [1] on chapter 11 put a code similar to this:
 
#include<iostream>
#include<vector>
using namespace std;
 
int main()
{

cin.unsetf(ios_base::dec);
cin.unsetf(ios_base::oct);
cin.unsetf(ios_base::hex);
 
int x;
 
cin >> x;
 
cout << x;
 
return 0;
}
 
Or equivalent:
 
#include<iostream>
#include<vector>
using namespace std;
 
int main()
{
cin.unsetf(ios_base::basefield);
 
int x;
 
cin >> x;
 
cout << x << endl;
 
return 0;
}
 
Running this program:
$ CC a.cpp
$ ./a.out
10
10
$ ./a.out
0xa
10
$ ./a.out
012
10
$
 
The book says "You can get >> to accept and correctly interpret the 0 and 0x prefixes. To do that, you 'unset' all the defaults.".
And if you see the first table, then you can see that the "stdio equivalent" is %i, exactly as expected because this:
http://stackoverflow.com/questions/1893490/difference-between-format-specifiers-i-and-d-in-printf
 
The "problem" is:
 
All the "stdio equivalent" can be reached using manipulators, with one exception: %i,
which requires the programmer to write manually the flags
 
Would not it be more appropriate, from the point of view of orthogonality, that there was a manipulator to cover that particular case? (That is, the
case where basefield has to be 0).
 
-------------------------------------------------------------------------
[1] http://www.stroustrup.com/programming.html / ISBN 978-0321-992789
[2] All tables are ordered. That is, the first line whose condition is true applies.
[3] ISO/IEC 14882:2011[E] Information technology — Programming languages — C++
Tables were generated by https://ozh.github.io/ascii-tables/
I have the original books/standard. I quote some fair minimal excerpts for research purpose.
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: May 05 05:03AM +0200

On 05-May-17 4:23 AM, Christiano wrote:
 
> Would not it be more appropriate, from the point of view of
> orthogonality, that there was a manipulator to cover that particular
> case? (That is, the case where basefield has to be 0).
 
Yes, I agree.
 
And not having it is inconsistent with having `std::defaultfloat`.
 
But of all the problems with iostreams, this must IMO count as one of
the least significant:
 
(1) it's just a lack of convenience, for as you have shown you can
easily clear the default decimal format (see C++14 §27.5.5.2/3 for the
defaults), and
 
(2) it's one to three lines of code to define the desired manipulator,
depending on how you format it, if you really want such manipulator.
 
I remember that in C++03 hex input was a problem, because overflow gave
formally UB for fscanf (I think it was) which was used to define the
effect of the >> operator. I proved to my own satisfaction that one
could make Visual C++ behave in an ungood way. That was fixed in C++11.
 
A nice approach is to read all user input via `getline`, and parse that.
 
 
Cheers!,
 
- Alf
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: