Saturday, September 10, 2022

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

Bonita Montero <Bonita.Montero@gmail.com>: Sep 10 06:16PM +0200

Am 09.09.2022 um 19:49 schrieb Lynn McGuire:
> The text contains requests for comments."
 
> I did not know that RS wrote the first gcc compiler.
 
> Lynn
 
C is a good language to learn programming
but actually not to solve real tasks.
scott@slp53.sl.home (Scott Lurndal): Sep 10 05:04PM


>> Lynn
 
>C is a good language to learn programming
>but actually not to solve real tasks.
 
I think you have that backwards. Really.
Michael S <already5chosen@yahoo.com>: Sep 10 12:56PM -0700

On Friday, September 9, 2022 at 8:49:42 PM UTC+3, Lynn McGuire wrote:
> The text contains requests for comments."
 
> I did not know that RS wrote the first gcc compiler.
 
> Lynn
 
I don't know about Linux, but on Windows in order to read his book, which, supposedly,
weigh 1 or 5 MB, one needs to download ~200 MB worth of software that expands to
~900 MB of disk space. And that's would be sufficient only if you already have msys2,
gcc, python, make and binutils installed. Which is true in case of myself, but but wrong
for 99% of Windows users. So, for those 99% there is a need to install another 2 or 5 GB.
 
I wonder, if RMS is doing it intentionally or out of ignorance.
Keith Thompson <Keith.S.Thompson+u@gmail.com>: Sep 10 03:53PM -0700

> On Friday, September 9, 2022 at 8:49:42 PM UTC+3, Lynn McGuire wrote:
>> "Richard Stallman Announces C Reference"
 
>> https://www.i-programmer.info/news/184-cc/15705-richard-stallman-announces-c-reference.html
[...]
> for 99% of Windows users. So, for those 99% there is a need to install
> another 2 or 5 GB.
 
> I wonder, if RMS is doing it intentionally or out of ignorance.
 
I wouldn't quite say it's deliberate, but RMS fairly clearly does not
care about Windows or other non-free software. He probably wouldn't go
out of his way to make things difficult on Windows, but I'm reasonably
sure he wouldn't expend any effort to make things easier. He wants
everyone to stop using Windows.
 
The pdf version is easy to generate *if* you already have the right
infrastructure, and I presume it will become available, which means
Windows users can use it directly.
 
(Please do not turn this into a debate about the merits of his
opinions.)
 
--
Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
Working, but not speaking, for Philips
void Void(void) { Void(); } /* The recursive call of the void */
Manu Raju <MR@invalid.invalid>: Sep 11 12:01AM +0100

On 09/09/2022 18:49, Lynn McGuire wrote:
> still in beta. The text contains requests for comments."
 
> I did not know that RS wrote the first gcc compiler.
 
> Lynn
 
How is this different from this file?
 
<https://gcc.gnu.org/onlinedocs/gcc-12.2.0/cpp.pdf>
"Chris M. Thomasson" <chris.m.thomasson.1@gmail.com>: Sep 10 01:53PM -0700

Has anybody tried to compile and run my seqlock experiment?
 
https://groups.google.com/g/comp.lang.c++/c/RYASx2cGqes/m/nEHS7VJsAgAJ
 
I am interested in your results.
Robert A <robert.art.green@gmail.com>: Sep 10 09:55AM -0700

Say I have a global variable `thing` with certain properties:
 
thing.foo
thing.bar
 
If I want `thing` to be lazily initialized on first use, I could turn all my uses of it into a function...
 
thing().foo
 
Thing &thing() {
if (!_instance) { _instance = new Thing; }
return *_instance;
}
 
Is there a way to get the same effect without the parens? Ie, so I can say `thing.foo`. I'm craving syntactic sugar.
 
Clang has an extension (__declspec) where you can put computed properties on a class. [1] I don't have a problem using a compiler extension, but I don't know of one do a similar thing with a global.
 
[1]: https://stackoverflow.com/a/49230152/327572
Richard Damon <Richard@Damon-Family.org>: Sep 10 01:40PM -0400

On 9/10/22 12:55 PM, Robert A wrote:
 
> Is there a way to get the same effect without the parens? Ie, so I can say `thing.foo`. I'm craving syntactic sugar.
 
> Clang has an extension (__declspec) where you can put computed properties on a class. [1] I don't have a problem using a compiler extension, but I don't know of one do a similar thing with a global.
 
> [1]: https://stackoverflow.com/a/49230152/327572
 
Evil preprocessor hack
 
#define thing thing_()
 
and then define Thing &thing_()
Richard Damon <Richard@Damon-Family.org>: Sep 10 01:43PM -0400

On 9/10/22 12:55 PM, Robert A wrote:
 
> Is there a way to get the same effect without the parens? Ie, so I can say `thing.foo`. I'm craving syntactic sugar.
 
> Clang has an extension (__declspec) where you can put computed properties on a class. [1] I don't have a problem using a compiler extension, but I don't know of one do a similar thing with a global.
 
> [1]: https://stackoverflow.com/a/49230152/327572
 
You could also define a class ThingProxy with a conversion function from
ThingProxy to Thing that creates the object if not already created.
 
The "ThingProxy" will be created at startup, but that is a trivial, the
Thing won't be created until used.
Robert A <robert.art.green@gmail.com>: Sep 10 11:00AM -0700

On Saturday, September 10, 2022 at 12:43:34 PM UTC-5, Richard Damon wrote:
> ThingProxy to Thing that creates the object if not already created.
 
> The "ThingProxy" will be created at startup, but that is a trivial, the
> Thing won't be created until used.
 
I was trying that, but haven't gotten it to work exactly yet. The code below is close. Do you have a way to get that last line to work?
 
struct Thing {
Thing() { cout << "Thing()" << endl; }
string foo = "foo value";
};
Thing *_thing = nullptr;
struct LazyThing {
operator const Thing&() {
cout << "op(Thing&)" << endl;
if (!_thing) {
_thing = new Thing;
}
return *_thing;
}
};
LazyThing thing;
int main()
{
// This works, but the cast syntax defeats the point.
cout << ((Thing)thing).foo << endl;
const Thing &t = thing;
cout << t.foo << endl; // works
cout << thing.foo << endl; // won't compile
}
Robert A <robert.art.green@gmail.com>: Sep 10 11:08AM -0700

On Saturday, September 10, 2022 at 1:00:26 PM UTC-5, Robert A wrote:
> struct Thing { ...
 
Sorry about the lack of indentation. I haven't posted here before. Apparently this browser-based google groups text editor just deletes the indentation I put at the start of a line.
Ben Bacarisse <ben.usenet@bsb.me.uk>: Sep 10 08:35PM +0100

> }
 
> Is there a way to get the same effect without the parens? Ie, so I can
> say `thing.foo`. I'm craving syntactic sugar.
 
If you are prepared to forego the dot and use -> instead, this pattern
 
class Thing {
struct ActualThing {
int foo;
int bar;
} actual_thing;
public:
const ActualThing *operator->() {
// Do what you like here to set up 'actual_thing'.
return &actual_thing;
}
};
 
gives you a function call at the time the member is accessed. You
could, as I think you were trying elsewhere, have a private pointer to
an 'actual_thing', and use that to decide if it needs to be allocated,
but that just means you need more machinery. There are lots of simpler
ways to ensure that 'actual_thing' gets initialised only once.
 
But I am tempted to ask what you are really doing. It looks odd to make
an object before the members can be usefully initialised.
 
--
Ben.
Robert A <robert.art.green@gmail.com>: Sep 10 01:34PM -0700

On Saturday, September 10, 2022 at 2:36:08 PM UTC-5, Ben Bacarisse wrote:
> [...] There are lots of simpler ways to ensure that 'actual_thing' gets initialised only once.
 
> But I am tempted to ask what you are really doing. It looks odd to make
> an object before the members can be usefully initialised.
 
Partly I'm just trying to learn what's possible in the language (C++). I've used lazy init in other languages for things that may or may not be needed as the program runs. In the real example that I'm working on currently, I don't really need the lazy init, because this `thing` is always used. The actual variable is called `loczn` and it holds properties and methods that give me localized strings throughout the UI code. I need to set it once as the program starts up, and reset to a different subclass it if the user's language preference changes. Another point is that I'd like it to have virtual functions on this thing (different languages, different subclasses). So I liked the idea of `thing`/`loczn` being a _reference_.
Muttley@dastardlyhq.com: Sep 10 09:17AM

On Fri, 9 Sep 2022 18:28:52 +0200
>which I'd have to write to reduce two non-predictible branches to one.
>If you've adapted this style the code becomes more readable than the
>manual optimizations.
 
It really doesn't.
Bonita Montero <Bonita.Montero@gmail.com>: Sep 10 11:53AM +0200

>> If you've adapted this style the code becomes more readable than the
>> manual optimizations.
 
> It really doesn't.
 
Then take my code, write the lambda expanded twice and think about
if that is more readable.
"Alf P. Steinbach" <alf.p.steinbach@gmail.com>: Sep 10 11:59AM +0200

On 9 Sep 2022 19:39, Mr Flibble wrote:
 
> Multiplication and logarithm/exponentiation are both equally inexact
> when we are dealing with IEEE 754 floating point.
 
No no no.
 
- Alf
Muttley@dastardlyhq.com: Sep 10 10:42AM

On Sat, 10 Sep 2022 11:53:31 +0200
 
>> It really doesn't.
 
>Then take my code, write the lambda expanded twice and think about
>if that is more readable.
 
face <- palm.
 
Never mind.
Mr Flibble <flibble@reddwarf.jmc.corp>: Sep 10 02:59PM +0100

On Sat, 10 Sep 2022 11:59:38 +0200
 
> > Multiplication and logarithm/exponentiation are both equally inexact
> > when we are dealing with IEEE 754 floating point.
 
> No no no.
 
Yes.
 
/Flibble
Mr Flibble <flibble@reddwarf.jmc.corp>: Sep 10 03:12PM +0100

On Sat, 10 Sep 2022 11:59:38 +0200
> > when we are dealing with IEEE 754 floating point.
 
> No no no.
 
> - Alf
 
Yes.
 
#include <iostream>
#include <cmath>
 
int main()
{
double const n = 0.123456789;
std::cout << (n * n * n) << std::endl;
std::cout << std::pow(n, 3.0) << std::endl;
std::cout << std::exp(3.0 * std::log(n)) << std::endl;
}
 
0.00188168
0.00188168
0.00188168
 
/Flibble
Mr Flibble <flibble@reddwarf.jmc.corp>: Sep 10 03:27PM +0100

On Sat, 10 Sep 2022 11:59:38 +0200
> > when we are dealing with IEEE 754 floating point.
 
> No no no.
 
> - Alf
 
Yes.
 
#include <iostream>
#include <cmath>
#include <limits>
#include <iomanip>
 
int main()
{
double const n = 0.123456789;
std::cout <<
std::setprecision(std::numeric_limits<double>::digits10 + 1);
std::cout << (n * n * n) << std::endl;
std::cout << std::pow(n, 3.0) << std::endl;
std::cout << std::exp(3.0 * std::log(n)) << std::endl;
}
 
0.001881676371789155
0.001881676371789155
0.001881676371789155
 
/Flibble
Bonita Montero <Bonita.Montero@gmail.com>: Sep 10 04:33PM +0200

Am 10.09.2022 um 16:12 schrieb Mr Flibble:
> 0.00188168
> 0.00188168
 
> /Flibble
 
Pow uses a row of multiplications of d ^ (2 ^ n) for each bit in the
exponent. With that you have only a logarithmic number of
multipli-cations. When you multiply N times in a row that might be less
exact.
 
#include <iostream>
 
int main()
{
double v = 1.5, r = v;
for( int i = 0; i != 30; ++i, r *= 1.5 )
std::cout << hexfloat << pow( 1.5, i ) - r << std::endl;
}
"Alf P. Steinbach" <alf.p.steinbach@gmail.com>: Sep 10 05:33PM +0200

On 10 Sep 2022 16:27, Mr Flibble wrote:
 
> 0.001881676371789155
> 0.001881676371789155
> 0.001881676371789155
 
You're a good programmer but you're lousy in maths :).
 
Consider:
 
 
----------------------------------------------------------------------
#include <float.h> // DBL_DIG
#include <math.h> // exp, log
#include <stdio.h> // printf
 
auto main() -> int
{
const double x = 3.0;
printf( "Multiplication yields 3^2 = %.*f.\n", DBL_DIG + 1, x*x );
printf( "exp/log yields 3^2 = %.*f.\n", DBL_DIG + 1, exp(
2*log( x ) ) );
}
----------------------------------------------------------------------
 
 
Output with Visual C++ 2020:
 
 
Multiplication yields 3^2 = 9.0000000000000000.
exp/log yields 3^2 = 9.0000000000000018.
 
 
- Alf
Mr Flibble <flibble@reddwarf.jmc.corp>: Sep 10 05:00PM +0100

On Sat, 10 Sep 2022 17:33:40 +0200
 
> Output with Visual C++ 2020:
 
> Multiplication yields 3^2 = 9.0000000000000000.
> exp/log yields 3^2 = 9.0000000000000018.
 
I may or may not be lousy at maths however you are completely
missing the point: we use double when we want to deal with real
numbers, if we want to deal with just integers then we use integer
types. IN GENERAL multiplication is just as inexect as exp/log when
using IEEE 754 floating point for the set of real numbers representable
by the floating point type.
 
Not that it materially effects anything, I note that x*x is likely
evaluated at compile time by the optimiser rather than at runtime.
 
/Flibble
Mr Flibble <flibble@reddwarf.jmc.corp>: Sep 10 05:25PM +0100

On Sat, 10 Sep 2022 17:33:40 +0200
 
> Output with Visual C++ 2020:
 
> Multiplication yields 3^2 = 9.0000000000000000.
> exp/log yields 3^2 = 9.0000000000000018.
 
Consider this:
 
#include <float.h> // DBL_DIG
#include <math.h> // exp, log
#include <stdio.h> // printf
 
auto main() -> int
{
const double x = 3.0;
printf( "Multiplication yields 3^3 = %.*f.\n", DBL_DIG + 1, x*x*x
); printf( "exp/log yields 3^3 = %.*f.\n", DBL_DIG + 1, exp(
3*log( x ) ) );
}
 
Output:
 
Multiplication yields 3^3 = 27.0000000000000000.
exp/log yields 3^3 = 27.0000000000000000.
 
Feel free to retract your assertion that I am lousy at maths.
 
/Flibble
"Alf P. Steinbach" <alf.p.steinbach@gmail.com>: Sep 10 07:54PM +0200

On 10 Sep 2022 18:25, Mr Flibble wrote:
 
> Multiplication yields 3^3 = 27.0000000000000000.
> exp/log yields 3^3 = 27.0000000000000000.
 
> Feel free to retract your assertion that I am lousy at maths.
 
Well let's just say that math is not what you're absolutely best at.
 
 
#include <float.h> // DBL_DIG
#include <math.h> // exp, log
#include <stdio.h> // printf
 
auto main() -> int
{
const double x = 3.0;
printf( "Multiplication yields 3^4 = %.*f.\n", DBL_DIG + 1, x*x*x*x );
printf( "exp/log yields 3^4 = %.*f.\n", DBL_DIG + 1, exp(
4*log( x ) ) );
}
 
 
Output:
 
 
Multiplication yields 3^4 = 81.0000000000000000.
exp/log yields 3^4 = 81.0000000000000284.
 
 
The tiny little difference can be arbitrarily amplified by e.g. rounding
up this result, or rounding down one that errs the opposite way. And
that can matter significantly. Often it will not matter, but it can.
 
And although Bonita has stated that it was not her intention to use her
code for integer base it is eminently usable for that, and that was the
main use case for my `constexpr` templated version `intpow` years ago.
 
I thought it was nice to be able to write e.g.
 
constexpr int k = intpow( 2, 10 );
 
Arguably a missing part of the standard library.
 
 
- 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: