Sunday, March 12, 2023

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

JiiPee <kerrttuPoistaTama11@gmail.com>: Mar 12 09:16AM +0200

On 12/03/2023 00:01, Mr Flibble wrote:
> second attempt at using it and I get a different problem this time for
> which I have raised a defect report:
 
> https://developercommunity.visualstudio.com/t/Problem-with-constexpr-and-accessing-non/10307212
 
I use VS in my full time work and also in personal use. For my use it is
working "well enough". No major issues for me. Also its free in personal
use, so a very good value. I think I had more problems with CodeBlocks,
so when VS was free again years ago I immediately changed back to VS.
MarioCPPP <NoliMihiFrangereMentulam@libero.it>: Mar 12 11:51AM +0100

On 12/03/23 08:16, JiiPee wrote:
> Also its free in personal use, so a very good value. I think
> I had more problems with CodeBlocks, so when VS was free
> again years ago I immediately changed back to VS.
 
do you happen to know if there is a "linux version" (like
visual studio CODE, community edition), running with its own
libraries or at worst on "mono" framework ?
 
I still long for Visual Studio (and I don't like Eclipse or
Code/Codium), I used to like it a lot years ago
 
 
 
--
1) Resistere, resistere, resistere.
2) Se tutti pagano le tasse, le tasse le pagano tutti
MarioCPPP
Sam <sam@email-scan.com>: Mar 12 07:35AM -0400

MarioCPPP writes:
 
> "mono" framework ?
 
> I still long for Visual Studio (and I don't like Eclipse or Code/Codium), I
> used to like it a lot years ago
 
At work it's easy to tell the wandering souls that use VS, or something
else. The VS ones always DM me screenshots of their code, instead of text.
Mr Flibble <flibble2@reddwarf.jmc.corp>: Mar 12 12:12PM

On 12/03/2023 07:16, JiiPee wrote:
> working "well enough". No major issues for me. Also its free in personal
> use, so a very good value. I think I had more problems with CodeBlocks,
> so when VS was free again years ago I immediately changed back to VS.
 
What the fuck is "well enough" supposed to mean? A C++20 compiler that
can't even compile well formed C++17 code is *not* fit for purpose.
 
/Flibble
Mr Flibble <flibble2@reddwarf.jmc.corp>: Mar 12 12:13PM

On 12/03/2023 11:35, Sam wrote:
>> Code/Codium), I used to like it a lot years ago
 
> At work it's easy to tell the wandering souls that use VS, or something
> else. The VS ones always DM me screenshots of their code, instead of text.
 
What point are you trying to make, mate?
 
/Flibble
JiiPee <kerrttuPoistaTama11@gmail.com>: Mar 12 07:25PM +0200

On 12/03/2023 12:51, MarioCPPP wrote:
"do you happen to know if there is a "linux version" ("
 
No I dont.
Bonita Montero <Bonita.Montero@gmail.com>: Mar 12 06:50PM +0100

Am 11.03.2023 um 23:01 schrieb Mr Flibble:
> second attempt at using it and I get a different problem this time for
> which I have raised a defect report:
 
> https://developercommunity.visualstudio.com/t/Problem-with-constexpr-and-accessing-non/10307212
 
I think MSVC is right here and an if constexpr isn't sth like a requires
clause which can contain invalid code and thereby evaluates to false.
Mr Flibble <flibble2@reddwarf.jmc.corp>: Mar 12 06:06PM

On 12/03/2023 17:50, Bonita Montero wrote:
 
>> https://developercommunity.visualstudio.com/t/Problem-with-constexpr-and-accessing-non/10307212
 
> I think MSVC is right here and an if constexpr isn't sth like a requires
> clause which can contain invalid code and thereby evaluates to false.
 
No, it is wrong and so are you.
 
/Flibble
Andrey Tarasevich <andreytarasevich@hotmail.com>: Mar 12 11:30AM -0700

On 03/12/23 5:12 AM, Mr Flibble wrote:
 
> What the fuck is "well enough" supposed to mean?  A C++20 compiler that
> can't even compile well formed C++17 code is *not* fit for purpose.
 
No compiler currently on the marked is "fit for purpose" from that
standpoint.
 
--
Best regards,
Andrey
Bonita Montero <Bonita.Montero@gmail.com>: Mar 12 08:05PM +0100

Am 12.03.2023 um 19:06 schrieb Mr Flibble:
 
>> I think MSVC is right here and an if constexpr isn't sth like a requires
>> clause which can contain invalid code and thereby evaluates to false.
 
> No, it is wrong and so are you.
 
"if constexpr" isn't a "if constexpr( requires() { { type() }; } )".
Mr Flibble <flibble2@reddwarf.jmc.corp>: Mar 12 08:06PM

On 12/03/2023 19:05, Bonita Montero wrote:
>>> clause which can contain invalid code and thereby evaluates to false.
 
>> No, it is wrong and so are you.
 
> "if constexpr" isn't a "if constexpr( requires() { { type() }; } )".
 
"requires" is C++20, "if constexpr" is C++17 in which statements can be
discarded in templates.
 
/Flibble
"Chris M. Thomasson" <chris.m.thomasson.1@gmail.com>: Mar 12 01:12PM -0700

On 3/12/2023 4:35 AM, Sam wrote:
>> Code/Codium), I used to like it a lot years ago
 
> At work it's easy to tell the wandering souls that use VS, or something
> else. The VS ones always DM me screenshots of their code, instead of text.
 
That's pretty harsh... ;^o
"Chris M. Thomasson" <chris.m.thomasson.1@gmail.com>: Mar 12 01:16PM -0700

On 3/12/2023 3:51 AM, MarioCPPP wrote:
 
> do you happen to know if there is a "linux version" (like visual studio
> CODE, community edition), running with its own libraries or at worst on
> "mono" framework ?
 
I don't think there is a native version of MSVC for Linux. They have one
for the Mac:
 
https://visualstudio.microsoft.com/vs/mac/
 
Fwiw:
https://learn.microsoft.com/en-us/cpp/linux/download-install-and-setup-the-linux-development-workload?view=msvc-170
 
 
 
Bo Persson <bo@bo-persson.se>: Mar 12 09:38PM +0100

On 2023-03-12 at 21:16, Chris M. Thomasson wrote:
 
> I don't think there is a native version of MSVC for Linux. They have one
> for the Mac:
 
> https://visualstudio.microsoft.com/vs/mac/
 
Unfortunately that is C# for the Mac, but not C++.
Sam <sam@email-scan.com>: Mar 12 05:24PM -0400

Mr Flibble writes:
 
 
>> At work it's easy to tell the wandering souls that use VS, or something
>> else. The VS ones always DM me screenshots of their code, instead of text.
 
> What point are you trying to make, mate?
 
You also don't have a second thought of taking a screenshot of a window with
code, cropping it in an image editor, and then sending the cropped picture
to someone else, with a programming-related question about the snapped code
snippet?
"Alf P. Steinbach" <alf.p.steinbach@gmail.com>: Mar 12 11:42AM +0100

On 2023-03-10 8:08 PM, Keith Thompson wrote:
 
> I wonder if it's a copy of "C++ Move Semantics The Complete Guide" by
> Nicolai M. Josuttis (which is available legally as an ebook from
> leanpub.com).
 
It is.
 
I don't know if it's legal.
 
But then I have retained a collection of formally illegal books that
I've downloaded to answer students questions about them, plus sometimes
my own nostalgic interest (e.g. Niklaus Wirth's "Algorithms + Data
Structures = Programs", unfortunately the only available version is the
visually ugly Oberon edition, not my beloved original Pascal version).
 
Association: Andrei Alexandrescu once expressed anger that I had
inadvertently accepted a clc++m article that referred to an illegal PDF
of his classic "Modern C++ Design" book. As I remember it I apologized.
I really hope that I remember that correctly. :(
 
I used to have that book on paper, one of the three C++ paper books I've
had (Bjarne's TCPPPL in 1st, 2nd and 3rd editions, K&R TCPL in 1st and
2nd editions, and Andrei's MCPPD in 1st edition), but somehow it's
disappeared; the only one I see now is TCPL.
 
- Alf
David Brown <david.brown@hesbynett.no>: Mar 12 11:54AM +0100

On 10/03/2023 17:20, Öö Tiib wrote:
 
> There are reasons why intrinsics like __builtin_saddll_overflow are
> there. Only that I do not want the code to call function named in Orcish
> and check a bool. I would like guaranteed terminate, signal or exception.
 
Even if it has not always been clear in this thread, I think we can
agree on quite a number of things:
 
Any code that attempts to execute code with undefined behaviour, is
buggy. In some cases, it might work well enough for a while and then
fail due to later changes (such as in the anecdote about strcpy).
 
Undefined behaviour which could be caught at compile/link time without
unreasonable compiler effort, should be caught there.
 
Some kinds of undefined behaviour - bugs in the code - could be detected
by run-time checks, with or without hardware support. If hardware can
handle the checks with no overhead, that's great. If there is overhead
in code speed or missed optimisation, that must be balanced against the
benefits of catching bugs.
 
(If you don't agree on these points, I hope you'll say so.)
 
 
I am of the opinion that if a language cannot define a particular
behaviour in a correct manner, then it should be left undefined. I see
no point in a language insisting on incorrect behaviour. Leaving it
undefined gives the implementation freedom to optimise on the assumption
that it does not happen when the user is looking for optimal efficiency,
and also to allow extra checks and debugging aids to help developers
find problems in their code. Defining behaviour limits that, while not
being able to give the programmer any useful benefits.
 
 
Let's take a couple of examples. For signed integer overflow, there are
two realistic possible definitions for behaviour - two's complement
wrapping, and trapping. (There are other possibilities, such as
saturation, but that's going to be inefficient on most hardware.) Some
languages, such as Java, use wrapping. For some simple expressions,
that is efficient on all realistic hardware - but for many expressions
it limits optimisations and is therefore less efficient. It guarantees
an incorrect answer in a lot of situations. And it stops tools from
being able to add checks and traps for bug-hunting aids, as the language
does not consider overflow to be an error. Thus it is often worse than
useless as a feature for general coding, even though it occasionally helps.
 
Some languages, such as Ada, consider overflow to be a run-time error
that must be detected, leading to an exception or other trapping
behaviour. That's great for debugging, but can be very inefficient in
practice, even when the programmer knows the calculation cannot overflow
(if the compiler can /prove/ there can be no overflow, it can omit the
checks). And when such exceptions are part of the defined behaviour,
the program needs to handle them - in many cases, there is no sensible
choice of behaviour for the program when it sees such errors, and any
code paths handling them are not seriously considered or seriously tested.
 
Other languages, such as Python, do not have overflow - the integer
types are extendable and grow as needed. That means you always get the
correct answer, but at such considerable run-time cost that it is not
appropriate for a language aimed at efficient compiled code.
 
So there are pros and cons of these possible ways of handling overflow,
but everything other than "undefined behaviour that is assumed not to
happen in correct code" has a cost. For something as low-level and
common as integer arithmetic, any cost can quickly become significant.
 
Whereas other languages are often fixed in their handling of overflow,
C++ is flexible - you can make your own classes to handle overflow just
the way you want. The language does not impose any choice on the users,
but provides the mechanisms to let you make whatever kinds of integers
you want with whatever overflow handling you want. (You can also do
C-style manual checks whenever you feel the need.)
 
 
As another common example of undefined behaviour, let's look at
dereferencing invalid pointers - such as attempting to access array
elements outside of the array's bounds. This is UB in C and C++. On
bigger systems, hardware (MMU) and software (the OS) combine to give
near zero-overhead trapping for accesses that are far out of bounds,
outside the memory space of the process. This is vital for secure and
reliable multi-program and multi-user systems. But it could not be
behaviour defined or required in the language standard, because many
smaller systems (typically single-program devices) cannot do anything
like this, and even on big systems the mechanisms can vary wildly.
 
For "close miss" errors, where the target address is inside the
processes' memory spaces, there is no general low-cost mechanism to
detect and prevent such invalid accesses. The language would require
"fat pointers" everywhere, with very different ways of dealing with
accesses, array slices, etc. Basically, the language would have to
remove the concepts of "pointer" and direct references entirely - fine
for slow, safe, interpreted Python but not appropriate for C or C++.
Leaving the behaviour undefined means tools can add checking (like
memory sanitizers or valgrind) for debugging, and optimise code that you
know is correct. Note also that there is no general way to determine if
an access will be a "close miss" or outside the processes' memory spaces.
 
And again, you can add whatever behaviour and checks you like for your
own use. Put in checks manually. Make your own "array" class that has
bound-checked indexing by default, if that's what suits you.
 
 
"Undefined behaviour" is key to how C and C++ work, and what makes them
great languages. It is utterly essential to the philosophy of "zero
overhead" and not paying for things you don't use. As a C and C++
programmer, it is /your/ choice and /your/ responsibility to make sure
the code is correct, and to choose whatever level of extra checking you
feel appropriate to the task in hand. With C++ you can make your
classes to automate this as needed - UB is vital to giving you that freedom.
David Brown <david.brown@hesbynett.no>: Mar 12 12:06PM +0100

On 11/03/2023 13:10, Öö Tiib wrote:
> micro-operations. There possibly is still hardware in usage where adding
> two integer registers takes multiple cycles but there is also hardware
> where 4 unrelated with each other adds in a row take one cycle.
 
I don't see how that observation fits the points above it. However, it
is worth noting that checked arithmetic - whether you are
bounds-checking before the arithmetic, or using overflow or carry flags
after the operation - absolutely cripples a modern processor's ability
to do things in parallel. It enforces a serialisation that can only
partially be offset by speculative execution. This cost is in addition
to the sometimes severe limitations it enforces on compiler
optimisations, expression re-arrangement, and code re-arrangement.
 
 
> It is relevant in sense that its rules should be about usefulness for
> programming software. The throughput and latency of operations into
> what it is translated can change.
 
The usefulness of C and C++ for programming is dependent on efficient
code generation. If that is not relevant, switch to Python and get
extending integers and exceptions on errors. (Plenty of programmers,
and plenty of programs, would be better off with a language like Python,
or at least a half-way choice like C#. "Trust the programmer" languages
are not the right choice for all purposes.)
"Öö Tiib" <ootiib@hot.ee>: Mar 12 09:29AM -0700

On Sunday, 12 March 2023 at 12:54:57 UTC+2, David Brown wrote:
> in code speed or missed optimisation, that must be balanced against the
> benefits of catching bugs.
 
> (If you don't agree on these points, I hope you'll say so.)
 
Basically I agree just that the trend is that even the bugs that are detected
on hardware level are ignored. That is like the effort of hardware designers
was wasted. Instead compilers often generate code that bypasses those
hardware checks and does something odd or even what programmers
did expect instead. So code generation is too much balanced towards
not catching bugs. That is pointless philosophy of unreliability.
 
> and also to allow extra checks and debugging aids to help developers
> find problems in their code. Defining behaviour limits that, while not
> being able to give the programmer any useful benefits.
 
The integer arithmetic has been very rarely important to performance
for very long time. It was already in nineties when people did show that
with simpler compression algorithms uncompressing can be quicker
than memcpy between two uncompressed buffers. Changes in integer
arithmetic are rarely needed for performance but often for correctness.
 
> but provides the mechanisms to let you make whatever kinds of integers
> you want with whatever overflow handling you want. (You can also do
> C-style manual checks whenever you feel the need.)
 
You reply to where I mentioned that programmers can write their own
trapping, (or saturating or wrapping) arithmetic using compiler intrinsics.
Those are not part of C++ language. C++ language is as unhelpful as it
only can. There is only undefined behavior available. How is that flexible?
So compiler writers have attempted to at least help a bit.
 
 
> And again, you can add whatever behaviour and checks you like for your
> own use. Put in checks manually. Make your own "array" class that has
> bound-checked indexing by default, if that's what suits you.
 
For those other examples there are even no compiler intrinsics.
Can do basically nothing but to use the skills accumulated with
decades to help out. Again, even if to remove quarter of undefined
behaviors the language would become simply better by that quarter.
There are no good or beneficial undefined behaviors.
 
> the code is correct, and to choose whatever level of extra checking you
> feel appropriate to the task in hand. With C++ you can make your
> classes to automate this as needed - UB is vital to giving you that freedom.
 
All people are fallible. They make mistakes with often boring stuff that
compiler could refuse or that hardware does already trap. It is no way
super "key feature" that those opportunities are ignored.
"Öö Tiib" <ootiib@hot.ee>: Mar 12 09:29AM -0700

On Sunday, 12 March 2023 at 13:06:40 UTC+2, David Brown wrote:
> partially be offset by speculative execution. This cost is in addition
> to the sometimes severe limitations it enforces on compiler
> optimisations, expression re-arrangement, and code re-arrangement.
 
Point is simply that things can and are made differently on hardware
level. You talk about software level checks before or after operation.
The expressions that are rearranged or ran in parallel are anyway proven
to be unrelated by compiler or hardware that does those.
> and plenty of programs, would be better off with a language like Python,
> or at least a half-way choice like C#. "Trust the programmer" languages
> are not the right choice for all purposes.)
 
There are needs where such choice is not available and so I have very
low experience with C# and Python. Also to throw decades of
experience away and to say that nah I now just make JavaScript
for web page would be irresponsible.
Malcolm McLean <malcolm.arthur.mclean@gmail.com>: Mar 12 09:57AM -0700

On Sunday, 12 March 2023 at 16:29:30 UTC, Öö Tiib wrote:
> with simpler compression algorithms uncompressing can be quicker
> than memcpy between two uncompressed buffers. Changes in integer
> arithmetic are rarely needed for performance but often for correctness.
 
On a big modern processor, the bottleneck will be memory access, in
particular cache misses.
However C and C++ are not used exclusively for big processors.
"Öö Tiib" <ootiib@hot.ee>: Mar 12 10:26AM -0700

On Sunday, 12 March 2023 at 18:57:17 UTC+2, Malcolm McLean wrote:
 
> On a big modern processor, the bottleneck will be memory access, in
> particular cache misses.
> However C and C++ are not used exclusively for big processors.
 
From that does not follow that integer arithmetic is bottle-neck on
small processors. Lets say your small processor does not have much
memory but can do about 16 millions operations per second. What the
heck it does for integer arithmetic to become bottle-neck for it?
Keith Thompson <Keith.S.Thompson+u@gmail.com>: Mar 12 02:17PM -0700

Öö Tiib <ootiib@hot.ee> writes:
[...]
> decades to help out. Again, even if to remove quarter of undefined
> behaviors the language would become simply better by that quarter.
> There are no good or beneficial undefined behaviors.
[...]
 
Which brings us back to the point I tried to make earlier.
 
Upthread, you wrote:
 
Most people agree that C++ contains too lot of features. They only
differ by opinion where to cut. I would put most effort into places
where it says "undefined behavior". I think half of such places can
be replaced with "program is ill formed", "std::terminate is called"
or one of the features that lead to described situation can be cut
out (as badly thought thru).
 
Now you talk about removing a quarter of undefined behaviors.
 
Leaving aside for the moment the fact that most cases of undefined
behavior are implicit, I was hoping for some indication of *which* cases
you think can be removed. I agree that there are some, but I'm
skeptical that it would be practical to remove as many has half.
 
Any comment on that?
 
--
Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
Working, but not speaking, for XCOM Labs
void Void(void) { Void(); } /* The recursive call of the void */
Frederick Virchanza Gotham <cauldwell.thomas@gmail.com>: Mar 12 05:41AM -0700

I mentioned a few weeks ago on this newsgroup about how I'm combining two programs into one.
 
Now I've put a GUI in there too, and so I want to capture all the output from the two programs and display the output in a text box on the screen.
 
Capturing everything sent to "printf" and "puts" can be achieved in GNU by using "fopencookie" and then changing the value of stdout, as follows:
 
FILE *const f = fopencookie( ........ );
stdout = f;
stderr = f;
 
I thought that this would automatically also capture everything from cout, cerr and clog, but it doesn't -- I reckon because under the bonnet, 'cout' is using the file descriptor 1 instead of using a FILE*. I tried constructing a streambuf from the FILE* returned from 'fopencookie' and then assigning this streambuf to cout, but this didn't work -- presumable because 'fileno' doesn't work on the FILE* returned from fopencookie.
 
So I wrote a new kind of streambuf class:
 
class streambuf_redirect : public std::streambuf {
 
using std::streambuf::streambuf;
 
virtual std::streamsize xsputn(char const *const s, std::streamsize const count)
{
return fwrite(fp_from_fopencookie,1u,count,s);
}
};
 
This works, and so now I am able to capture all the output sent to standard output by printf, puts, fprint(stderr,...), cout <<, clog <<, cerr <<.
 
Everything works fine except for one: It doesn't capture the output from "puts". It works on "fputs(stdout,....)", but not on "puts". I've compiled and linked everything with -fno-builtin but that doesn't fix it. I've tried taking the address of 'puts' in a volatile function pointer and then using the function pointer to invoke it, but that doesn't work either.
 
I've gone on the Github for glibc and compared the implementations of puts and fputs side by side, and I can see why I'm failing to capture puts.
 
Anyone got any ideas?
Frederick Virchanza Gotham <cauldwell.thomas@gmail.com>: Mar 12 06:03AM -0700

On Sunday, March 12, 2023 at 12:42:06 PM UTC, Frederick Virchanza Gotham wrote:
 
> It doesn't capture the output from "puts".
 
I figured it out. I can capture the output from puts if I remove unprintable characters afterward:
 
for ( std::size_t i = 0u; i < s.size(); ++i )
{
using std::isprint;
using std::isspace;
 
char unsigned const c = static_cast<char unsigned>(s[i]);
 
if ( false == (isprint(c) || isspace(c)) )
{
s.erase(i,1u);
--i;
}
}
 
There must be some dodgy bytes in there -- I'll check what they are another time. For now I have a fix to keep me going.
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: