Saturday, November 17, 2018

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

woodbrian77@gmail.com: Nov 17 12:58PM -0800

I was until today laboring under the idea that I needed to
mark all non-template functions in header files as inline.
Then I read on reddit/learnprogramming:
 
"Almost all templates and constexpr values are implicitly inline. Also any function defined inside a class."
 
It's the last part about functions defined inside a class that
I didn't know or had forgotten. I've now updated my software:
https://github.com/Ebenezer-group/onwards
 
and tested that this is kosher with both gcc and clang. Removing
the superfluous inline keywords didn't make any difference to
the size of the text segments for gcc 8.2, but for clang 7.0 it
led to a bit smaller text segments.
 
I'm encouraged by these events and ask for further review of my software.
 
 
Brian
Ebenezer Enterprises - "The L-RD is near to the brokenhearted; He saves the contrite in spirit. Many are the afflictions of the righteous, but the L-RD delivers him from them all." Psalms 34:18-19
http://webEbenezer.net
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Nov 17 10:20PM +0100

> mark all non-template functions in header files as inline.
> Then I read on reddit/learnprogramming:
 
> "Almost all templates and constexpr values are implicitly inline. Also any function defined inside a class."
 
That's very wrong, pure disinformation.
 
A function defined inside a class is implicitly `inline`, yes.
 
However, a freestanding function template is not, and a `constexpr` is not.
 
If you fully specialize a function template you don't get an `inline`
function, unless you add the keyword `inline`. So you can easily run
into multiple definition errors. It depends on what you do.
 
If you take the address of a not explicitly inlined `constexpr` value in
two different translation units, you get two different addresses. If you
do that with an `inline` value you get the same address.
 
 
> the size of the text segments for gcc 8.2, but for clang 7.0 it
> led to a bit smaller text segments.
 
> I'm encouraged by these events and ask for further review of my software.
 
Hm, encouraged by disinformation that Seems To Work™.
 
 
Cheers!,
 
- Alf
woodbrian77@gmail.com: Nov 17 02:07PM -0800

On Saturday, November 17, 2018 at 3:20:47 PM UTC-6, Alf P. Steinbach wrote:
 
> That's very wrong, pure disinformation.
 
> A function defined inside a class is implicitly `inline`, yes.
 
> However, a freestanding function template is not, and a `constexpr` is not.
 
Well, I have some freestanding function templates that aren't
marked as inline and neither gcc 8.2 or clang 7.0 say anything
about that. I'm not sure it's a problem.
 
> > led to a bit smaller text segments.
 
> > I'm encouraged by these events and ask for further review of my software.
 
> Hm, encouraged by disinformation that Seems To Work™.
 
I don't know if the author intended to muddy the waters.
At any rate, it was helpful to me in that some of it was
accurate.
 
 
Brian
Robert Wessel <robertwessel2@yahoo.com>: Nov 17 09:38AM -0600

On Fri, 16 Nov 2018 00:15:53 -0800 (PST), Paul <pepstein5@gmail.com>
wrote:
 
>I'm going to attempt to use these instructions to fix the issue:
>https://dev.my-gate.net/2014/09/15/how-to-use-mingw-w64-with-clion/
 
>Please let me know if you have anything else to add.
 
 
If you want a short, bit-by-bit, algorithm, why not just do the more
conventional basic approach or repeatedly shifting x right? Note that
I've changed the type to unsigned. Not tested, etc:
 
int popcnt(unsigned x)
{
int count = 0;
while (x)
{
count += x & 1;
x /= 2;
}
return count;
}
 
FWIW, GCC generates a rather shorter loop for that too.
Jorgen Grahn <grahn+nntp@snipabacken.se>: Nov 17 04:15PM

On Thu, 2018-11-15, Paul wrote:
> This explains why it wasn't all optimized away.
 
> I changed to -O3 optimization. I'm not sure whether this is best
> or what you would advise (?).
 
With gcc I tend to use -O2 or -Os. Sometimes -O3, if I can show that
it generates measurably faster code. But the main thing is enabling
the optimizer at all.
 
/Jorgen
 
--
// Jorgen Grahn <grahn@ Oo o. . .
\X/ snipabacken.se> O o .
Ben Bacarisse <ben.usenet@bsb.me.uk>: Nov 17 09:17PM


>>> On Thu, 15 Nov 2018 12:35:46 -0800 (PST), Paul <pepstein5@gmail.com>
<snip>
>>> > ++count;
 
>>> > return count;
>>> > }
<snip>
> return count;
> }
 
> FWIW, GCC generates a rather shorter loop for that too.
 
There's a neat way to clear the least significant set bit:
 
int count = 0;
for (; x; count++) x &= x - 1;
return count;
 
It may of course be slower, but when you have only a few bits set it may
pay off.
 
--
Ben.
Paul <pepstein5@gmail.com>: Nov 17 01:20PM -0800

> return count;
> }
 
> FWIW, GCC generates a rather shorter loop for that too.
 
Your code is significantly faster than mine and avoids the problematic
comparison in my code.
The reason I coded it the way I did is that I was looking for the most
direct approach so I said "What's happening in the kth binary place" So this
led to me introducing 1 << place.
x/=2; seems to execute faster than x >>= 1; so maybe a problem with my code
is that bit shifting isn't as fast as the alternatives. I'm not sure why my code is so much slower than yours -- it seems to take about 1.5 times as long to execute.
 
Paul
Paul <pepstein5@gmail.com>: Nov 17 01:25PM -0800

On Saturday, November 17, 2018 at 9:17:31 PM UTC, Ben Bacarisse wrote:
> return count;
 
> It may of course be slower, but when you have only a few bits set it may
> pay off.
 
I think this trick, popularised (or maybe even invented) by Kernighan
is known to be much faster in general than naive bit by bit methods.
 
It's a better big O. Your method is O(number of bits set) which is
better than O(log n). It doesn't need to have "only a few bits set" to
pay off. It pays off in general. It might be worse in cases where
almost all the bits are set -- I haven't tested.
 
Paul
Paul <pepstein5@gmail.com>: Nov 17 02:55AM -0800

Using a recent version of gcc, the below code (at end of post) doesn't compile.
Presumably, this is because "unsigned int" is interpreted as
"unsigned int int" which, I agree, does not make sense.
 
It seems to be a precedence problem.
std::cout << ( (unsigned int)(230)); works fine.
 
Presumably a C++ expert would know that the below code doesn't
compile without needing to try it.
Why does the compiler not recognise unsigned int as the type "unsigned"
in the below context?
 
Thanks,
 
Paul
 
 
#include<iostream>
int main()
{
std::cout << (unsigned int(230));
}
Bo Persson <bop@gmb.dk>: Nov 17 07:43PM +0100

On 2018-11-17 11:55, Paul wrote:
> {
> std::cout << (unsigned int(230));
> }
 
Check the rules for "Explicit type conversion"
 
https://en.cppreference.com/w/cpp/language/explicit_cast
 
In particular case 2), which states:
 
"The functional cast expression consists of a simple type specifier or a
typedef specifier (in other words, a single-word type name: unsigned
int(expression) or int*(expression) are not valid)[...]"
 
 
Bo Persson
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Nov 17 09:20PM +0100

On 17.11.2018 11:55, Paul wrote:
> compile without needing to try it.
> Why does the compiler not recognise unsigned int as the type "unsigned"
> in the below context?
 
Because C++ got the botched declaration syntax from C, and use rules
that don't accommodate that syntax.
 
One might say that the message is, don't use C declaration syntax except
to the degree that it suits C++.
 
The source code formatting impact of that is:
 
* One thing declared per declaration.
* Focus on types, with type builders like `*` viewed as basic type
modifiers instead of thing type modifiers: space between type and thing.
* Declarations as close to first use as practically possible.
 
 
> {
> std::cout << (unsigned int(230));
> }
 
The simplest remedy is to just omit the word `int`, which is implicit
anyway:
 
cout << unsigned( V )
 
Another remedy is to use a C++ named cast:
 
cout << static_cast<unsigned int>( V )
 
Or, third remedy, you can define
 
template< class T > Type_ = T;
 
... and then write
 
cout << Type_<unsigned int>( V )
 
The last approach also lets you use prefix `const` wherever you wish, so
that you can do that /consistently/, which I think is great.
 
 
Cheers & hth.,
 
- Alf
m.labanowicz@gmail.com: Nov 17 10:49AM -0800

Hi,
 
How to force gcc to complain about ambiguity.
 
Following there is example:
 
--{beg:main.cpp}---------------------------------
#include <iostream>
class A {
public:
A() : x(new int) { *x = 0; }
virtual ~A() { delete x; }
virtual void run() { std::cout << (void *)this << ":" << *x << std::endl; }
private:
int * x;
};
class B : public A {
public:
B(A & a) : a(a) { }
virtual void run() { a.run(); }
private:
A & a;
};
int main(void) {
A a;
 
A other;
B b(other);
 
a.run();
b.run();
 
A * ptrA = new B(a);
#if 1 // wrong
A * ptrB = new B(b); // <------ this is the point of issue
// simple allocation and copy Memory is executed
// instead of defined Constructor
#else // good
A * ptrB = new B(static_cast<A &>(b));

No comments: