Sunday, May 3, 2015

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

ram@zedat.fu-berlin.de (Stefan Ram): May 03 11:59AM

>pointless to use 'constexpr' just to detect if a constructor
>or function matches with (quite loose in C++14) requirements
>for those.
 
When a function or constructor is declared with »constexpr«,
the compiler will choose to calculate it at compile time
when feasible. This will never hurt (?) and sometimes speed
up program execution, since some values do not have to be
calculated at run time. So one should always use »constexpr«
when possible. /Not/ because we can thus detect whether C++
requirements are fulfilled, /but/ because we want the
program to run as fast as possible!
 
In the special case of »complex«, there is an additional
reason: A complex number should behave as similar to a
double as possible. Since »double« is a "literal type" we
want complex to be a "literal type" too.
ram@zedat.fu-berlin.de (Stefan Ram): May 03 04:02PM

>There is no "problem" with it, if it works (theoretically) and
>accomplishes what you mean it to accomplish. However, as you can
>probably judge, it's recursive,
 
(Disclaimer: I never wrote a destructor and I never wrote a
»delete« call, so the following might be utter nonsense:)
 
The »delete head« deletes the next node and, IIRC, that will
(recursively) invoke the destructor for the next node.
So, there is no need for the while loop!
 
So, one should decide whether a recursive solution is wanted.
if so, one can eliminate the redundant »while«.
 
Otherwise, an iterative solution might be possible by setting
»head->next = 0;« after it has been saved, so that the
»delete head;« will not continue to recurse.
ram@zedat.fu-berlin.de (Stefan Ram): May 03 04:39PM

I posted this program into another newsgroup, where the
topic was how short a program to calculate a product of
sums of values can be in various programming languages:
 
#include <iostream>
#include <ostream>
#include <initializer_list>
 
int main()
{ auto const X ={ 1, 2 };
auto const Y ={ 3, 4 };
double r = 1.0;
for( int const x : X )for( int const y : Y )r *= x + y;
::std::cout << r << '\n'; }
 
. Then, I wondered how short I can make it when I do not
follow my usual stylistic guidelines. The following still
works under the C++ implementation used:
 
#include <iostream>
int main()
{auto X={1,2},Y={3,4},r=1;for(int x:X)for(int y:Y)r*=x+y;std::cout<<r;}
 
But why is
 
auto X={1,2},Y={3,4},r=1;
 
actually possible? The type deduced for »{1,2}« should be
«initializer_list<int>«, while the type deduced for »r«
should be »int«, so it's not the same type!
 
(If you would write »r=1.«, then the implementation /would/
complain that the types do not match.)
legalize+jeeves@mail.xmission.com (Richard): May 03 02:18AM

[Please do not mail me a copy of your followup]
 
Doug Mika <dougmmika@gmail.com> spake the secret code
 
>Well, I found something on function pointers, but id didn't cover how it
>looks when your function returns these.
>That is, until I found the following piece of code I attach below
 
What you found in a piece of C code.
 
Please don't code C in C++.
 
Use C++ mechanisms and abstractions to achieve your purposes instead of
C mechanisms and its limited abstractions.
 
Function pointers are how C achieves variability of function, but C++
has better mechanisms: classes, virtual methods and templates to name
just a few.
 
Function pointer syntax gets ugly quite quickly, which is one of the
reasons that people often use them with typedefs in order to make things
sane again. If you just use the abstraction mechanisms in C++ instead,
you can return to normalcy.
--
"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>
Permil Garg <garg.permil@gmail.com>: May 03 09:25AM -0700

> {OPER_TAN, tan},
> {OPER_SQUARE, square},
 
> };
 
This is a array of struct (oper) which named oper_lut[] and it is initialized with 4 values. In braces, the value of array to initialize. Before (,) is the enum value and after (,) is function name.
Paul <pepstein5@gmail.com>: May 03 02:51AM -0700

No, this is not for a homework or class assignment. I am trying to learn this stuff independently.
 
The below is my attempt to write a destructor for a linked list. I'm suspicious of it because it seems different and somewhat simpler than the answers I've seen online. I'd be grateful if someone could tell me if there's a problem with it. Thank you.
 
Paul
 
struct LinkedList
{
int data;
LinkedList* next;
~LinkedList();
};
 
LinkedList::~LinkedList()
{
while(next)
{

LinkedList* head = next;
next = head->next;
delete head;
 
}
 
}
Victor Bazarov <v.bazarov@comcast.invalid>: May 03 11:35AM -0400

On 5/3/2015 5:51 AM, Paul wrote:
> No, this is not for a homework or class assignment. I am trying to
learn this stuff independently.
 
> The below is my attempt to write a destructor for a linked list. I'm
suspicious of it because it seems different and somewhat simpler than
the answers I've seen online. I'd be grateful if someone could tell me
if there's a problem with it. Thank you.
> delete head;
 
> }
 
> }
 
There is no "problem" with it, if it works (theoretically) and
accomplishes what you mean it to accomplish. However, as you can
probably judge, it's recursive, and that could mean a problem if your
linked list grows to be too long for the execution environment to
handle. You're going to learn about it eventually, so you might start now.
 
Recursion is usually organized using the process' stack (automatic
storage), which is often limited. In order to avoid putting too much
stress on the stack, it is advisable to replace recursion with a loop
whenever possible. I'll leave it to you to convert this recursive
function into a proper loop.
 
V
--
I do not respond to top-posted replies, please don't ask
Paavo Helde <myfirstname@osa.pri.ee>: May 03 11:05AM -0500

Paul <pepstein5@gmail.com> wrote in
> next = head->next;
> delete head;
 
> }
 
It seems you are trying to delete everyhing twice ('delete head' already
deletes head->next recursively so there is no need for the while loop).
Double-deleting a pointer is illegal, so the program is invalid. On the
other hand, deleting a NULL pointer is a well-defined non-op, so in
principle you could have even simpler constructor:
 
LinkedList::~LinkedList()
{
delete next;
}
 
However, this is a recursive call, which may cause troubles (stack
overflow) with huge lists, so a while loop would be in principle better.
Alas, your variant of it was invalid.
 
Cheers
Paavo
Melzzzzz <mel@zzzzz.com>: May 03 06:06PM +0200

On Sun, 03 May 2015 11:35:03 -0400
 
> > }
 
> > }
 
> There is no "problem" with it, if it works (theoretically)
 
It does not works...
woodbrian77@gmail.com: May 02 09:20PM -0700

http://www.dailymail.co.uk/sciencetech/article-3064915/Is-internet-brink-collapse-web-reach-limit-just-eight-years-warn-engineers.html
 
The article says,
 
"Storing information in large 'server farms', rather than
transferring it, would take the strain off the network."
 
This is the approach I've taken with the C++ Middleware Writer --
files are only copied across the network if they have been updated.
I did this more to reduce bandwidth costs than thinking the
internet was unstable. I hope this article will encourage people
to consider their bandwidth consumption.
 
Brian
Ebenezer Enterprises - In G-d we trust.
http://webEbenezer.net
scott@slp53.sl.home (Scott Lurndal): May 03 03:30PM

>transferring it, would take the strain off the network."
 
> I hope this article will encourage people
>to consider their bandwidth consumption.
 
I would hope that article teaches people to be less
gullible. The _Daily Mail_? Give me a break.
 
 
>Brian
>Ebenezer Enterprises - In G-d we trust.
 
Never mind, too late.
Bo Persson <bop@gmb.dk>: May 03 09:55AM +0200

On 2015-05-03 00:14, Stefan Ram wrote:
> possible and there were comments that suggested this to him.
 
> What do you think why he did not use »constexpr« at the
> beginning of the constructors and some member functions?
 
Perhaps he just didn't see any immediate use for compile time complex
arithmetic?
 
 
Bo Persson
"Öö Tiib" <ootiib@hot.ee>: May 03 03:30AM -0700

On Sunday, 3 May 2015 01:14:19 UTC+3, Stefan Ram wrote:
> beginning of the constructors and some member functions?
> Could there be any drawback of using »constexpr«, when it
> is possible?
 
Even the latest betas of Microsoft compilers do not support
'constexpr' too well. Herb Sutter is lead architect of Microsoft
C++ compilers so can not publish C++ code that puts those into
bad light.
 
> it might be difficult to change the interface later when,
> for some reason, the constructor or function cannot be
> implemented as constexpr any longer.)
 
We should use 'constexpr' functions and constructors where we
plan to use these for producing constant expressions. It is
pointless to use 'constexpr' just to detect if a constructor
or function matches with (quite loose in C++14) requirements
for those.
"Öö Tiib" <ootiib@hot.ee>: May 03 06:10AM -0700

On Sunday, 3 May 2015 14:59:27 UTC+3, Stefan Ram wrote:
> when possible. /Not/ because we can thus detect whether C++
> requirements are fulfilled, /but/ because we want the
> program to run as fast as possible!
 
'constexpr' does not make function to run compile time nor does lack
of it guarantee that it does not run compile time so your point is
moot.
 
Besides how you teach software development without knowing at all
what our work is about?
 
First we want the program that we make to do what it should do.
Second we want it to work as correctly as it is possible. Everything
else (like speed of its run and such) is of secondary importance
until those two goals have been met.
 
Unfortunately these primary goals are most hard to reach. What it
should do is often unknown (or more precisely imagined naively) even
to its authors and stakeholders and what it does follows the
requirements (even those naive interpretations) always incorrectly
or imprecisely at least in some corner cases. So we typically
gradually maintain it closer and closer to what it should actually
do as our knowledge grows.
 
Marking every function possible as 'constexpr' does not aid with
neither of two primary goals and it only distracts during
maintenance. Example: So we discover that we clearly need to add a
try-catch into some function but originally it was marked as
'constexpr'. Why? Maybe author used it somewhere to make constant
expressions. Remove it and rebuild. Half our later ... does not
seem to be the case. Maybe code makes constant expressions with it
under some other build options? Can't build all the configurations
out of blue so lets see all the 1000 calls of it. Hours later ...
no ... we may add try-catch. Author did put 'constexpr' there just
to waste our time.
 
> reason: A complex number should behave as similar to a
> double as possible. Since »double« is a "literal type" we
> want complex to be a "literal type" too.
 
About why Herb Sutter designed 'complex' like he did I already
answered and you snipped it. Can't you avoid bringing back
discussions that you snipped? Here it goes again:
"Herb Sutter is lead architect of Microsoft C++ compilers so
he can not publish C++ code that puts those into bad light."
Bo Persson <bop@gmb.dk>: May 03 08:31AM +0200

On 2015-05-02 16:39, Stefan Ram wrote:
 
> ? The second »::« is the binary "scope resolution operator",
> but is the first unary one also called "scope resolution
> operator"?
 
It really IS the same operator in both places. It just so happens that
the global namespace has no name, so its position looks empty.
 
 
Bo Persson
"Öö Tiib" <ootiib@hot.ee>: May 02 06:04PM -0700

On Sunday, 3 May 2015 01:00:39 UTC+3, Paavo Helde wrote:
> specifically fixed a gap in an area which prevented achieving maximum
> performance in certain high-level programming style. It is under the
> control of the programmer to use or not use this style.
 
'register' keyword did mean one day that variable will occupy a register.
Now it only means that one may not take reference of the variable or
parameter. 'inline' keyword did mean one day that the function should
be inlined. Now it only means that defining the function several times
copy-paste in the same program is not ODR violation.
It is so because such decision gave better performance.
 
Move semantics puts it into programmers hands to indicate if a value
passed will end its duration for next anyway so it may be moved instead
of copied. It may happen that it will be also decay into "hint" one
day that is easier for compiler actually to decide (for better performance).
 
> porton of programmers and programs would move away to some other language
> to retain the maximum performance (to Fortran or C, possibly to something
> else branched off from C++ (D?)).
 
I did not mean that C++ is adding or should start adding any overhead. I
mean that the programmers somehow manage to add complications and so
cause overhead with anything.
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: