Thursday, January 26, 2017

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

ram@zedat.fu-berlin.de (Stefan Ram): Jan 26 10:55PM

>So, Why does it work when there are two types in template
>definition and just use one? Does It automatically identify
>the second type reading the argument type?
 
Yes. It is a function template, not a class template.
And for function templates, template arguments
can often be deduced. That's why we got so many
»make_...« functions. But I believe there are some
deduction capabilities for other entities on the way.
Christiano <christiano@engineer.com>: Jan 26 02:46PM -0800

See the following program:
 
==== a.cpp ===========
#include "std_lib_facilities.h"
 
int main(void)
try {
int x1 = narrow_cast<int>(2.9);
 
return 0;
}
catch(exception &e) {
cerr << "**** ERROR: " << e.what() << "\n";
keep_window_open();
 
return 1;
}
=== end a.cpp ========
 
Running it:
debian@debian:~/principles$ ./a.out
**** ERROR: info loss
Press enter a character to exit
q
debian@debian:~/principles$
 
The narrow_cast definition uses TWO template types but it is used with only one ==> narrow_cast<int>(2.9);
 
narrow_cast here:
http://www.stroustrup.com/Programming/PPP2code/std_lib_facilities.h
 
template<class R, class A> R narrow_cast(const A& a)
{
R r = R(a);
if (A(r)!=a) error(string("info loss"));
return r;
}
 
So, Why does it work when there are two types in template definition and just use one? Does It automatically identify the second type reading the argument type?
goodmullah@gmail.com: Jan 25 11:14PM -0800

class MyClass
{
public:
MyClass(int questionsCount)
{
this->questionsCount = questionsCount;
answers = new int[questionsCount]; // allocating space
for (int i = 0; i < questionsCount; i++)
{
answers[i] = -1;
}
}
~MultipleChoiceTest()
{
delete [] answers; // <------- (1)
delete answers; (2)
}
 
protected:
int questionsCount;
 
private:
int* answers;
};
 
 
In the class above in the destructor I am not sure if (1) has to be used or (2) ..... My best guess would be (2) as i only have one pointer not an array of pointers ... Am I right ??
"Öö Tiib" <ootiib@hot.ee>: Jan 26 12:45AM -0800

> int* answers;
> };
 
> In the class above in the destructor I am not sure if (1) has to be used or (2) ..... My best guess would be (2) as i only have one pointer not an array of pointers ... Am I right ??
 
You can't have destructor ~MultipleChoiceTest() in class
MyClass. Idea for the future: paste compiling code to your posts.
Otherwise your defects distract and confuse the audience.
 
You used new[] to allocate 'answers' so you should use delete[]
to deallocate those as well. However in general it is not advisable
to use raw pointer for dynamic size array in C++ since we have
std::vector that already does what we usually need to do with
dynamic sized array and it does that more safely:
 
#include <vector>
 
class MyClass
{
public:
// define types we use so if we need to change those
// later then less changes needed
using Ints = std::vector<int>;
using Count = Ints::size_type;

// use explicit here to avoid various ints silently
// converting into Myclass
explicit MyClass(Count questionsCount)
: answers(questionsCount, -1)
{}
 
protected:
Count questionsCount() {return answers.size();}
 
private:
Ints answers;
};
 
int main()
{
MyClass plorp(15);
}
 
 
Compiler-generated default destructor, copy constructor/assignment
and move constructor/assignment are all fine for MyClass like above.
In your implementation these were defective.
legalize+jeeves@mail.xmission.com (Richard): Jan 26 09:17PM

[Please do not mail me a copy of your followup]
 
goodmullah@gmail.com spake the secret code
 
>In the class above in the destructor I am not sure if (1) has to be
>used or (2) ..... My best guess would be (2) as i only have one
>pointer not an array of pointers ... Am I right ??
 
Match scalar delete with scalar new:
 
int *one = new int;
delete one;
 
Match array delete with array new:
 
int *bunches = new int[10];
delete[] bunches
 
There are source code analysis tools that will catch mismatched
array/scalar new/delete.
 
From this code, it looks like you are just learning the language.
From this perspective you need to understand the low-level new and
delete operators and how they are used.
 
From a practical day-to-day perspective, you don't really need to
handle raw pointers much. Instead you use an appropriate "resource
container" for dynamically allocated memory. Need a dynamically
resizable array? Use std::vector. Need an object allocated on the
heap? Use std::unique_ptr or std::shared_ptr for unique or shared
ownership of the allocated object. Resource container classes manage
the raw pointers for you, so you don't need to worry about how you
should call new or how you should call delete.
--
"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>
CTG <BadMullah@gmail.com>: Jan 25 04:56PM -0800

bool b1,b2;
 
double value =0.0
 
if( value > std::numeric_limits<double>::min() ) b1 = 1; else b1=0;
if( value < std::numeric_limits<double>::max() ) b2 = 1; else b2=0;
cout << b1 <<","<< b2<< endl;
 
 
outputs : 0,1
 
What am i missing here?
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Jan 26 02:04AM +0100

On 26.01.2017 01:56, CTG wrote:
> cout << b1 <<","<< b2<< endl;
 
> outputs : 0,1
 
> What am i missing here?
 
For integers min and max are the ends of the entire value range.
 
For floating point types they are the ends of the strictly positive
value range. Then down from min towards 0, depending on the
implementation there may be a range of steadily less precise denormal
values. Then 0, and symmetrically down in the negative range.
 
That may be what you're missing, or maybe you're missing out on the
`condition? value1 : value2` notation?
 
 
Cheers!,
 
- Alf
CTG <BadMullah@gmail.com>: Jan 25 05:13PM -0800

On Thursday, January 26, 2017 at 11:56:48 AM UTC+11, CTG wrote:
Daniel <danielaparker@gmail.com>: Jan 25 05:17PM -0800

On Wednesday, January 25, 2017 at 7:56:48 PM UTC-5, CTG wrote:
> cout << b1 <<","<< b2<< endl;
 
> outputs : 0,1
 
> What am i missing here?
 
Notwithstanding its name, and unlike its counterpart
std::numeric_limits<int>::min(), std::numeric_limits<double>::min() doesn't
give the minimum value for that type, it gives 0.
-std::numeric_limits<double>::max() gives the minimum double value. Why? Who
knows.
 
Daniel
Daniel <danielaparker@gmail.com>: Jan 25 05:30PM -0800

On Wednesday, January 25, 2017 at 8:18:00 PM UTC-5, Daniel wrote:
 
> Notwithstanding its name, and unlike its counterpart
> std::numeric_limits<int>::min(), std::numeric_limits<double>::min() doesn't
> give the minimum value for that type, it gives 0.
 
Sorry, it gives the smallest minimum normalized positive value. So not sure about your result.
 
Daniel
Christiano <christiano@engineer.com>: Jan 25 07:55PM -0800

From the standard C++11, 18.3.2.4
"For floating types with denormalization, returns the minimum positive normalized value."
 
step by step
For floating types: http://babbage.cs.qc.cuny.edu/IEEE-754.old/Decimal.html
with denormalization: http://stackoverflow.com/questions/8341395/what-is-a-subnormal-floating-point-number
returns the minimum positive: self-explanatory
normalized value: not subnormal
 
Calculating:
https://en.wikipedia.org/wiki/Double-precision_floating-point_format
The minimum normal number double precision is
0 00000000001 0000000000000000000000000000000000000000000000000000
=
2^(1-1023)
=
https://www.wolframalpha.com/input/?i=%282^%28-1022%29%29
=
2.22507385850720138309023271733240406421921598046233 × 10^-308
 
Comparing using c++:
 
#include <limits>
#include <iostream>
using namespace std;
 
int main()
{
cout << std::numeric_limits<double>::min() << endl;
}
 
Result:
2.22507e-308
Chris Vine <chris@cvine--nospam--.freeserve.co.uk>: Jan 26 10:27AM

On Wed, 25 Jan 2017 16:56:41 -0800 (PST)
> b2=0; cout << b1 <<","<< b2<< endl;
 
> outputs : 0,1
 
> What am i missing here?
 
This is a weirdity inherited by C++ from C.
 
If you want the largest negative number supported by double rather
than the smallest positive number, use
std::numeric_limits<double>::lowest(), available since C++11. With
C++-98/03 you had to use -std::numeric_limits<double>::max() to obtain
that value, which would work with IEEE 754 floating points (ie, those
supplied by the C++ standard) but not necessarily for others.
 
With integer types, std::numeric_limits::min() gives the same value as
std::numeric_limits::lowest().
Daniel <danielaparker@gmail.com>: Jan 26 10:54AM -0800

On Thursday, January 26, 2017 at 5:27:50 AM UTC-5, Chris Vine wrote:
 
> If you want the largest negative number supported by double rather
> than the smallest positive number, use
> std::numeric_limits<double>::lowest(), available since C++11.
 
One more thing I didn't know about. Thanks!
 
Daniel
red floyd <dont.bother@its.invalid>: Jan 25 04:11PM -0800

On 1/25/2017 11:29 AM, Christiano wrote:
 
> return 0;
> }
> // }=========== end get++.cpp ======
 
In addition to what everyone else has said, the value of c or v
if the read fails is completely undefined.
red floyd <dont.bother@its.invalid>: Jan 25 04:12PM -0800

On 1/25/2017 4:11 PM, red floyd wrote:
[redacted]
> In addition to what everyone else has said, the value of c or v
> if the read fails is completely undefined.
 
Due to uninitialized local variable.
Ben Bacarisse <ben.usenet@bsb.me.uk>: Jan 26 12:29AM

>> 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
 
A C FILE object does have a persistent end-of-file state which can be
tested using the feof function. The Language standard says that EOF (or
whatever other failure indicator is used) must be returned when that
indicator is set but it is cleared in a few situations: freopen, ungetc
and fseek being the only ones I can recall at the moment.
 
The comparatively well-known behaviour being described for the C input
library makes it technically non-conforming: C states that fgetc must
return EOF when the end-of-file indicator is set and a program that
prints that indicator shows a little more:
 
#include <stdio.h>
 
int main(void)
{
int c;
c = fgetc(stdin);
printf("1: %d\n", c);
if (feof(stdin)) {
c = fgetc(stdin);
printf("2: %d\n", c);
}
}
 
Closing the input with Ctrl-D then trying 'a' and enter gives:
 
1: -1
a
2: 97
 
<snip>
--
Ben.
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Jan 26 01:39AM +0100

On 26.01.2017 01:29, Ben Bacarisse wrote:
 
> 1: -1
> a
> 2: 97
 
I concede that I may be wrong about C. I just took the OP's example for
granted, reasoning that it had the same behavior as low-level Unix
calls. But your example shows the same, a /not/ persistent EOF state?
 
Cheers!, and a bit baffled,
 
- Alf
Ben Bacarisse <ben.usenet@bsb.me.uk>: Jan 26 12:55AM


> I concede that I may be wrong about C. I just took the OP's example
> for granted, reasoning that it had the same behavior as low-level Unix
> calls. But your example shows the same, a /not/ persistent EOF state?
 
The state is persistent but it's just ignored if a subsequent input
operation could succeed. But it's a system-specific corner case in that
as far as C is concerned the state is not only persistent but also it
must be honoured. The program above should not print the second line on
a conforming implementation.
 
--
Ben.
Christiano <christiano@engineer.com>: Jan 25 09:31PM -0800

Thanks, Bo and Alf, I understood the problem by reading your answers.
 
The get++.cpp go straight through the second cin because "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. " (As said by Bo)
 
In tdx.cpp, the situation is different, "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." (As said by Alf)
 
Ben, this "new chance after EOF" exists since the classic programming books C, as highlighted by Alf. I did a search on standard C11 and found this function:
 
7.21.10 Error-handling functions
7.21.10.1 The clearerr function
Description
The clearerr function clears the end-of-file and error indicators for the stream pointed to by stream.
Jorgen Grahn <grahn+nntp@snipabacken.se>: Jan 26 03:53PM

On Wed, 2017-01-25, Alf P. Steinbach wrote:
>> 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.
 
The "readslow" example would, I suspect, translate to Unix "tail -f"
today. And I do indeed use that a lot.
 
On the other hand, I don't ever want to see programs which treat EOF
as a record separator on standard input. In that sense, it still
seems to me the feature is of use in very specific situations.
 
>> and that a program is better off honoring the EOF. Especially since
>> the behavior is limited to interactive use.
 
> Well, that's incorrect.
 
The tail -f example, yes.
 
> You can read more about it in my reply to the OP, earlier.
 
The one quoting "The Unix Programming Environment". Yes, and thanks.
 
/Jorgen
 
--
// Jorgen Grahn <grahn@ Oo o. . .
\X/ snipabacken.se> O o .
woodbrian77@gmail.com: Jan 25 07:15PM -0800

On Wednesday, January 25, 2017 at 1:18:37 PM UTC-6, Alf P. Steinbach wrote:
> > 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.
 
I tried that but ran into a problem when I catch exceptions
using std::exception. I don't really want to have to have
an additional catch block (in various places) for my exceptions.
 
 
> 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 sure if you mean to use string_view in the implementation
or in the class/constructor interface. I've thought about using it
in the interface, but haven't gotten there yet. Thank you for your
comments.
 
 
Brian
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: