Friday, February 17, 2017

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

"Rick C. Hodgin" <rick.c.hodgin@gmail.com>: Feb 16 03:38PM -0800

What does it do? What's an example of its use? Pseudo-code will be
fine for an example.
 
Since it's really powerful, It would be wrong to pass it up due to my
own ignorance.
 
Thank you,
Rick C. Hodgin
Ramine <toto@toto.net>: Feb 17 11:23AM -0500

On 2/16/2017 6:38 PM, Rick C. Hodgin wrote:
> own ignorance.
 
> Thank you,
> Rick C. Hodgin
 
It's used also in finite element method:
 
In this paper, we introduce a special way to store only the nonzero
elements of the stiffness matrix to obtain an efficient parallel
algorithm to solve partial differential equations with finite element
method. This storage method is obtained by considering the structure of
the mesh and the form of the stiffness matrix. The size of the matrix is
"the number of unknowns" by "a constant" instead of "the number of
unknowns" by "the number of unknowns". Our method and algorithm are
efficient in both time and memory. Experimental results are presented.
 
http://www.sciencedirect.com/science/article/pii/S0096300303002790
 
 
 
And read about Conjugate gradient method:
 
https://en.wikipedia.org/wiki/Conjugate_gradient_method
 
 
 
Thank you,
Amine Moulay Ramdane.
Tim Rentsch <txr@alumni.caltech.edu>: Feb 17 07:30AM -0800

>[...]
 
> Now while I suppose someone could define a pow() that is, itself, a
> constexpr, I've never seen it done.
 
That's an interesting exercise: define a function
 
constexpr long double cepow( long double x, long double y );
 
that calculates x**y (please excuse my fortran). Probably easier
in C++14 but still doable in C++11 (and the accuracy looks fairly
good in the tests I ran).
Tim Rentsch <txr@alumni.caltech.edu>: Feb 17 07:19AM -0800

> reference!, but the impression it leaves that gcc's `#include_next`
> preprocessor extension is needed to implement things in a reasonably
> practical way, is just propaganda. [..alternate scheme described..]
 
I think the point intended is that #include_next is needed if you
want to implement a set of C++ headers on top of an existing set
of regular C headers, with the C headers being left exactly as is,
including paths and file names. I don't know if strictly speaking
this is absolutely requires something like #include_next, but I
don't see any straightforward way around it.
Tim Rentsch <txr@alumni.caltech.edu>: Feb 17 07:08AM -0800

> use a T&
> - if you need to allow for no-object referred, use a T*
 
> It is clear, compact and type safe. What more?
 
What if you want a variable that is guaranteed to refer to an
actual object, but now and then you want to change which object
it refers to?
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Feb 17 04:12PM +0100

On 17.02.2017 16:08, Tim Rentsch wrote:
 
> What if you want a variable that is guaranteed to refer to an
> actual object, but now and then you want to change which object
> it refers to?
 
That's std::reference_wrapper<T> for you.
 
Copy assignment of a `std::reference_wrapper` makes it refer to another
object.
 
 
Cheers!,
 
- Alf
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Feb 17 04:05PM +0100

On 17.02.2017 14:23, Stefan Ram wrote:
 
> All of you who wonder how one might implement a stack array
> that is claimed to be portable to some extend might have a
> look at »stack_array« in the GSL (guideline support library).
 
I haven't looked at it because any such implementation that uses
`alloca` runs into two main problems:
 
• Failure of `alloca` cannot be reliably detected in a portable manner,
since the function isn't standard.
 
• There is no portable way to know if the resulting object is directly
on the call stack. If it isn't, then hasta la vista baby. Safety here
requires compiler support, which for portability means language support.
 
If instead of `alloca` one allocates in LIFO order from some buffer,
then that's another kettle of piranha. It introduces runtime checking of
LIFO call behavior, with corresponding possibility of runtime errors,
and it has that buffer laying unused most of the time in the call tree
below the buffer's declaration. Still it might be a worthwhile approach
for speeding up e.g. encoding conversions.
 
Perhaps also worth noting, if one should run into this esoteric
function: `std::get_temporary_buffer()` has nothing to do with stack
allocation, but rather with ¹allocating as much as currently possible up
to and possibly beyond some specified limit.
 
 
Cheers!,
 
- Alf
 
Links:
¹ See <url:
http://stackoverflow.com/questions/3264299/why-do-i-need-stdget-temporary-buffer>
Tim Rentsch <txr@alumni.caltech.edu>: Feb 17 06:28AM -0800

> questions. Here asking about the problem parameters is key. If we know
> nothing about the dictionary, we have to look at every word in it.
 
> If we know its sorted, however ..
 
Right. In this particular case I'm not sure that knowing
the input is sorted provides any help. But I agree with
your point generally.
Tim Rentsch <txr@alumni.caltech.edu>: Feb 17 07:04AM -0800

>> since my program was written in C rather than C++.)
 
> Why comparing performance of C program with C++ program may be is
> bit unfair?
 
Because programming in C you don't get distracted by wanting to
use all that template crap. ;) okay j/k.
 
Somewhat more seriously, being in a C++ environment naturally
nudges one's thinking towards the built-in maps, sets, vectors,
etc, and sometimes that interferes with run-time speed. My first
few attempts at writing this code were done in C++. I picked my
structures carefully, looking at the time guarantees for the
various types and methods. Despite that the performance wasn't
that good - not bad, but not good either. I thought about the
problem some more and came up with a different approach. The new
approach didn't need any STL types, and although I didn't try it
I think they would have gotten in the way more than helping. The
code I wrote uses fixed arrays, does no allocation, and in the
fast path uses pointer manipulation rather than array indexing.
No doubt all this could have been done in C++, but it would have
looked very un-C++-like. Or to say it another way, the primary
focus was speed rather than "nicely abstract" code, and I think
that was easier to accomplish in this case in C than it would
have been in C++.
 
Does that all make sense?
Tim Rentsch <txr@alumni.caltech.edu>: Feb 17 06:23AM -0800


>> http://imgur.com/FPkvQ91
 
> I hope you wrote to the author and publisher and got their
> permission to post that.
 
I believe it would be allowed under the "Fair use" doctrine.
(Needless to say IANAL.)
David Brown <david.brown@hesbynett.no>: Feb 17 09:07AM +0100

On 17/02/17 00:21, Chris Vine wrote:
> you can get round that by wrapping the reinterpret_cast within a
> function call, but then std::memcpy or a union is clearer and more
> convenient.)
 
Wrapping in a function call does not help avoid strict aliasing rules
unless the function is defined in a separately compiled TU - in which
case it is inefficient. And if your setup includes link-time
optimisation of sufficient sophistication, the function call does not
help at all.
 
> standard which says so explicitly: it seems to be taken to be implied
> by the statement in the standard that "at most one of the non-static
> data members of an object of union type can be active at any time".
 
The C89 standard said that type-punning through unions was undefined
behaviour. C++ based their rules on that C standard, but as far as I
can tell reading a union member that was not the last one written
(except for the "common start sequence of structs" exception) is
undefined behaviour in C++ by virtue of not having an defined behaviour
- unlike in C89 where it is explicitly labelled "undefined".
 
> optimized out by the compiler. It will end up like a union without the
> small prospect of undefined behavior on unknown compilers.
> reinterpret_cast is a last resort.
 
Yes - memcpy is usually efficient for such purposes. But it is still
ugly :-)
Chris Vine <chris@cvine--nospam--.freeserve.co.uk>: Feb 17 12:20PM

On Fri, 17 Feb 2017 09:07:36 +0100
David Brown <david.brown@hesbynett.no> wrote:
[snip]
> case it is inefficient. And if your setup includes link-time
> optimisation of sufficient sophistication, the function call does not
> help at all.
 
Types have gone by link time. I think it would be impossible to treat
the return value or out parameter of a function in the way you mention
at that time. Indeed, many functions (iconv comes to mind) rely on this
by returning arrays of bytes which you are expected to cast to an array
of an integer type of the right size, which may not in fact represent
the dynamic type used in constructing the byte array. Some of the
BSD-style networking functions do something similar.
David Brown <david.brown@hesbynett.no>: Feb 17 02:42PM +0100

On 17/02/17 13:20, Chris Vine wrote:
>> optimisation of sufficient sophistication, the function call does not
>> help at all.
 
> Types have gone by link time.
 
Not if you have link-time optimisation. The compiler can keep whatever
information it wants, allowing for exactly the same kinds of
optimisations and transforms as if all the definitions were in one huge
file.
 
My point is that using a function call to try to force an isolation like
this is not something you can rely on.
 
ram@zedat.fu-berlin.de (Stefan Ram): Feb 17 12:53AM

In hour 6 of my course, I only have explained operators and
function calls so far. I just have showed them
 
main.cpp
 
#include <iostream> // ::std::cout
#include <ostream> // <<
#include <string> // "s
#include <cstdlib> // ::std::rand
 
using namespace ::std::literals;
 
int main() { ::std::cout << ::std::rand() << "\n"s; }
 
::std::cout
 
41
 
(We only edit what's between »<<« and »<<« in the last line
and ignore the rest of the program in this part of the course.)
 
A partecipant wanted to see the next random number,
so he tried:
 
main.cpp
 
#include <iostream> // ::std::cout
#include <ostream> // <<
#include <string> // "s
#include <cstdlib> // ::std::rand
 
using namespace ::std::literals;
 
int main() { ::std::cout << 0*::std::rand()+1*::std::rand() << "\n"s; }
 
::std::cout
 
18467
 
Good idea! What number do you expect the following program
to print (we used a recent GCC, BTW)?
 
main.cpp
 
#include <iostream> // ::std::cout
#include <ostream> // <<
#include <string> // "s
#include <cstdlib> // ::std::rand
 
using namespace ::std::literals;
 
int main() { ::std::cout << 1*::std::rand()+0*::std::rand() << "\n"s; }
 
I was slightly surprised.
 
(A good teaching example for the unspecified order of
evaluation in C++, when an implementation is used that shows
this »effect«!)
ram@zedat.fu-berlin.de (Stefan Ram): Feb 17 01:34AM

>James Kanze fixed that. No longer necessary to include `<iostream>` (for
>this). Retroactively, this means that the examples in the C++03 standard
>are no longer incorrect. :)
 
/That/ /was/ explain in the course.
 
(I explained to the participants why »ostream« is /not/
needed and then that it is /my personal preference/ to
include it nonetheless.)
 
>>#include <string> // "s
>>#include <cstdlib> // ::std::rand
>I'd rather include `<stdlib.h>`. Less trouble.
 
Why is it less trouble?
 
>>int main() { ::std::cout << ::std::rand() << "\n"s; }
>>::std::cout
>Huh what's that?
 
Sorry! One needs to guess that it's the label preceding
the output of the program.
 
>>int main() { ::std::cout << 0*::std::rand()+1*::std::rand() << "\n"s; }
...
>>int main() { ::std::cout << 1*::std::rand()+0*::std::rand() << "\n"s; }
...
>>I was slightly surprised.
 
Or »mildly surprised«. I was not really shocked to the bone.
 
>Oh, that's what you wanted to show.
 
I did /not start out/ to want to show it to the participants
with this example (the sum above), but the example came
/from a participant/, and then I was able to explain its
output. But I might keep and use it for subsequent courses.
 
>Instead of the arithmetic hack the student could just use a
>comma-expression. ;-)
 
I have already did one exercise today to prepare the mind
for the comma expression, but I will not really introduce it
in this course due to lack of time.
 
(My exercise was a question along these lines: "Assume a
hypothetical operator »o« whose result is its left operand,
what would be the value of »4o7«?" - The main point of this
exercise is just to check the understanding of the words
"operator" and "operand", the secondary point preperation
for the comma operator. In fact, today in the classroom,
the wrong answer »7« was given due to a confusion between
"left" and "right"!)
 
>The advanced student, still limited to edit the single expression, could
>put a lambda there, and do just about anything.
 
At this point in the course they are only supposed to have
already learned:
 
- simple int numerals
- double numerals with ».«
- double numerals with »E«
- string literals "..."s
- (C string literals "..." - just as an information)
- the types »int«, »double«, »::std::string« (and »char*«)
- the unary operators »-« and »+«
- the parentheses operator (I deem »(2)« to be an
application of a unary circumfix operator)
- the binary operators »+«, »-«, »/«, and »*«
- that there are simple predefined names such as »INT_MAX«
- how to call parameterless functions that return a value
- that for predefined names and functions, an include
directive has to be written at the top of the program
- how to read documentation for names and functions
 
>I think C++ would have been better off with always well-defined and
>predictable evaluation of expressions.
 
I think there are some forces trying to get something like
this into future standards IIRC. Maybe not "always", but "for
some cases".
ram@zedat.fu-berlin.de (Stefan Ram): Feb 17 01:23PM

>call has a literal value as argument). And so in standard C++ this is
>not valid code. In standard C++ the size of an array variable must be
>compile time constant.
 
All of you who wonder how one might implement a stack array
that is claimed to be portable to some extend might have a
look at »stack_array« in the GSL (guideline support library).
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Feb 17 02:02AM +0100

On 17.02.2017 01:53, Stefan Ram wrote:
 
> main.cpp
 
> #include <iostream> // ::std::cout
> #include <ostream> // <<
 
James Kanze fixed that. No longer necessary to include `<iostream>` (for
this). Retroactively, this means that the examples in the C++03 standard
are no longer incorrect. :)
 
 
> #include <string> // "s
> #include <cstdlib> // ::std::rand
 
I'd rather include `<stdlib.h>`. Less trouble.
 
 
> using namespace ::std::literals;
 
> int main() { ::std::cout << ::std::rand() << "\n"s; }
 
> ::std::cout
 
Huh what's that?
 
 
 
> int main() { ::std::cout << 0*::std::rand()+1*::std::rand() << "\n"s; }
 
> ::std::cout
 
> 18467
 
This different result is not guaranteed, because the order of evaluation
is unspecified.
 
 
 
> (A good teaching example for the unspecified order of
> evaluation in C++, when an implementation is used that shows
> this »effect«!)
 
Oh, that's what you wanted to show.
 
Well.
 
Instead of the arithmetic hack the student could just use a
comma-expression. ;-)
 
The advanced student, still limited to edit the single expression, could
put a lambda there, and do just about anything.
 
I think C++ would have been better off with always well-defined and
predictable evaluation of expressions.
 
 
Cheers!,
 
- Alf
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Feb 17 04:42AM +0100

On 17.02.2017 02:34, Stefan Ram wrote:
 
> (I explained to the participants why »ostream« is /not/
> needed and then that it is /my personal preference/ to
> include it nonetheless.)
 
Yes, I meant `<ostream>`. Thanks.
 
 
 
>>> #include <cstdlib> // ::std::rand
>> I'd rather include `<stdlib.h>`. Less trouble.
 
> Why is it less trouble?
 
If you inadvertently forget to qualify something from the header and it
works with your compiler, then with `<stdlib.h>` the code will still
work with other compilers. See the recent thread about it, "Is std
library allowed to pollute the global namespace?".
 
And unqualified names are less to both read and write.
 
Plus it's IMHO also good to be familiar with most all names from the C89
standard library, so that one can avoid using them as names of stuff one
defines.
 
 
Cheers!,
 
- Alf
David Brown <david.brown@hesbynett.no>: Feb 17 09:17AM +0100

On 17/02/17 02:02, Alf P. Steinbach wrote:
 
 
> I think C++ would have been better off with always well-defined and
> predictable evaluation of expressions.
 
Isn't that coming in C++17 ?
 
I think it is unnecessary to have a predictable evaluation order for
"f() + g()" - we've lived with that for decades. But people often
expect the evaluation order for "cout << f() << g();" to be defined, and
/that/ will be useful.
Juha Nieminen <nospam@thanks.invalid>: Feb 17 10:54AM

> #include <iostream> // ::std::cout
> #include <ostream> // <<
 
"Let's include iostream, which includes both istream and ostream.
Let's then include ostream. Beacuse we like repetition so much.
And because we just love all those #include lines. We need more of them!"
 
And because reasons!
 
> #include <cstdlib> // ::std::rand
 
Isn't std::rand() deprecated or something? At least it should be.
 
Way to teach the use of functions they shouldn't be using.
 
> int main() { ::std::cout << ::std::rand() << "\n"s; }
 
Yeah, because that's so much more efficient than "\n".
And it adds so much to the code. (As in, nothing but potential
overhead. But who cares about that? The important thing is to
use fancy new C++ features! Except we are still using std::rand(),
because reasons!)
 
 
> ::std::cout
 
> 18467
 
> Good idea!
 
I hope that was sarcasm.
Chris Vine <chris@cvine--nospam--.freeserve.co.uk>: Feb 17 11:23AM

On Fri, 17 Feb 2017 09:17:36 +0100
 
> > I think C++ would have been better off with always well-defined and
> > predictable evaluation of expressions.
 
> Isn't that coming in C++17 ?
 
Probably.
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0145r3.pdf

JiiPee <no@notvalid.com>: Feb 17 11:26AM

On 17/02/2017 10:54, Juha Nieminen wrote:
 
>> #include <cstdlib> // ::std::rand
> Isn't std::rand() deprecated or something? At least it should be.
 
> Way to teach the use of functions they shouldn't be using.
 
I cannot see it being deprecated , but its not a good random function. I
guess you could teach it but needs to mention that this is not a good
one. I think rand() is ok for testing purposes because its much faster
to code. But not using in a serious application. I kind of wish std
would have a shortcut to rand() so we do not need to write those 6 lines
of code to get a simple random number.... I guess I could create my own
rand_ex? Thats a good idea by the way :). I recommend people to have
their "c_tools.h" file to add in all projects and then create maybe
rand_ex() to do it in c++11 way.
Chris Vine <chris@cvine--nospam--.freeserve.co.uk>: Feb 17 11:49AM

On Fri, 17 Feb 2017 11:23:07 +0000
> > "f() + g()" - we've lived with that for decades. But people often
> > expect the evaluation order for "cout << f() << g();" to be defined,
> > and /that/ will be useful.
 
However, on looking at the latest available print of the standard
(n4640), large parts of the proposal on the order of evaluation of
expressions and function arguments have been rejected.
"Rick C. Hodgin" <rick.c.hodgin@gmail.com>: Feb 16 09:24PM -0800


> Brian
> Ebenezer Enterprises
> http://webEbenezer.net
 
I upgraded to Bitbucket 4.x this evening. It was a completely painless
experience. The new version was $10 to download one-time fee. I used
postgresql and was up and running, importing my existing repositories
(all of them) from GitHub within 30 minutes. It has support for 10
users.
 
It took me longer to figure out how to setup postgresql and to generate
an api token on GitHub than it did to setup everything in BitBucket.
 
I've been impressed with Atlassian since I first found them 2015. I
continue to be impressed with each new release. (Note: I have no
affiliation with Atlassian, except that I used Stash and Bitbucket).
 
https://www.atlassian.com/software/bitbucket
 
Thank you,
Rick C. Hodgin
Jeff-Relf.Me <@.>: Feb 16 03:37PM -0800

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: