Thursday, December 5, 2019

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

Tim Rentsch <tr.17687@z991.linuxsc.com>: Nov 28 01:52PM -0800


> Is it reasonable that vs2019 produces a warning
 
> warning C4127: conditional expression is constant
> consider using 'if constexpr' statement instead
 
Let me rephrase your question as a multiple choice:
 
"A compiler operating under default option settings
produces this warning message for the above program.
Would you be more likely to describe this choice as
 
(A) reasonable, or
 
(B) monumentally stupid?"
 
Asked like this, my answer would be (B).
 
There are, I am sure, a large number of related questions,
for which I expect I would give various answers depending
on the particular question.
David Brown <david.brown@hesbynett.no>: Nov 29 09:30AM +0100

On 29/11/2019 06:09, Daniel wrote:
>> job at optimising.
 
> Which raises the question, what is the point of the constexpr if statement anyway?
 
> Daniel
 
The part omitted by the false branch has to be able to compile, but
otherwise doesn't affect the code. For example:
 
const bool return_int = true;
 
auto foo(void) {
if constexpr(return_int) {
return 1;
} else {
return 1.0;
}
}
 
The return type of "foo" is determined by the "if constexpr". Without
the "constexpr", you would get an inconsistent deduction for the return
type.
 
Typically, you will see "if constexpr" in templates, I expect.
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Nov 29 07:41AM +0100

On 29.11.2019 06:09, Daniel wrote:
>> technically a C++ constant or not), then the compiler is doing a poor
>> job at optimising.
 
> Which raises the question, what is the point of the constexpr if statement anyway?
 
Two main points:
 
* It communicates to a human reader that the expression is evaluated at
compile time, guaranteed.
* In a function template the path not taken in a given instantiation,
can contain code that wouldn't compile in that instantiation.
 
Maybe more, but it's late in the day for me.
 
- Alf
David Brown <david.brown@hesbynett.no>: Nov 30 12:03PM +0100

On 30/11/2019 01:52, Öö Tiib wrote:
 
> It was while(1) versus for(;;) last I saw anyone bothering to discuss
> those and these are still as apparently equivalent as these were back
> then.
 
I always use "while (true)" - and all my programs have that at least
once, being small embedded systems.
 
I have never liked the look of "for (;;)" - and I fear that some email
programs will turn it into a rather weird smiley!
Robert Wessel <robertwessel2@yahoo.com>: Nov 29 02:42PM -0600

On Fri, 29 Nov 2019 09:23:27 +0100, David Brown
>remember that any oddities I see in MSVC may be alleviated by switches).
> But I will definitely try to remember /W4 instead of /Wall. I guess
>MSVC takes "/Wall" more literally than gcc "-Wall".
 
 
That's about true. /Wall is actually pretty much *everything* in
MSVC. /W4 is pretty much everything rational in most cases, more like
what you get with GCC's -Wall plus most of -Wextra.
Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk>: Nov 29 04:33PM

On 27/11/2019 14:03, Alf P. Steinbach wrote:
 
> It's reasonable here because `n < m` is always true, which is known at compile time, and `||` has short-circuit evaluation, which means that the non-`constexpr` empty checking of the string is not considered.
 
> If you switch the values of `n` and `m` then `if constexpr` can no longer be used, because then, though the result is also then knowable at compile time, it isn't /necessarily/ known at compile time. The compiler needs some smarts to understand that `s.empty()` must be `false` here.
 
> That said, I find the Visual C++ warning about constant conditions to be generally unreasonable. For example, it pops up if you write `while(2+2 == 4)` instead of the slightly more idiomatic `for(;;)`. Apparently it no longer does that for `while(true)`, but I just don't trust it, it's evidently tuned to ignore one special literal case, and that's it.
 
VC++ is correct to warn about while(2+2 == 4) and not for(;;) the later being the only acceptable why to do an endless loop (I don't agree that while(true) is just as good as it is syntactically less clean). The reason why VC++ is correct to warn about while(2+2 == 4) is that one of those 2's could be a typo and a variable was meant instead.
 
/Flibble
 
--
"Snakes didn't evolve, instead talking snakes with legs changed into snakes." - Rick C. Hodgin
 
"You won't burn in hell. But be nice anyway." – Ricky Gervais
 
"I see Atheists are fighting and killing each other again, over who doesn't believe in any God the most. Oh, no..wait.. that never happens." – Ricky Gervais
 
"Suppose it's all true, and you walk up to the pearly gates, and are confronted by God," Byrne asked on his show The Meaning of Life. "What will Stephen Fry say to him, her, or it?"
"I'd say, bone cancer in children? What's that about?" Fry replied.
"How dare you? How dare you create a world to which there is such misery that is not our fault. It's not right, it's utterly, utterly evil."
"Why should I respect a capricious, mean-minded, stupid God who creates a world that is so full of injustice and pain. That's what I would say."
David Brown <david.brown@hesbynett.no>: Nov 28 12:37PM +0100

On 28/11/2019 11:58, Bo Persson wrote:
> /Fo"x64\Release\" /Ot /Fp"x64\Release\quick_test_ms.pch"
> /diagnostics:column
 
> Don't know exactly which one makes the difference.  :-)
 
OK. As I said, I don't know the command line switches for MSVC - I just
used the ones I knew for optimisation, warnings and standard version.
David Brown <david.brown@hesbynett.no>: Nov 29 09:15AM +0100

On 29/11/2019 00:14, Alf P. Steinbach wrote:
> you get a redefinition warning.
 
> And for example, regarding the so far not mentioned visual impact, the
> shouting uppercase is an annoying eyesore.
 
To be fair, you don't have to use all-caps for macros. Personally, I
only use all-caps for macros if the fact that it is a macro is
important. So I would write:
 
#define noOfWotsits 10
 
just as I would write
 
enum { noOfWotists = 10 };
static const int noOfWotsits = 10;
const int noOfWotsits = 10; // C++ only
 
depending on the language (C, C++, or compatible with both) and what I
want to be able to do with it. Disregarding scoping, these will all
have the same effect in almost all sensible uses - I see no earthly
reason to insist that one version should be written in all-caps and the
others in your favourite multi-word style (snake, camel, etc.).
 
But if I had written this macro (which I would not do - it's just an
example):
 
#define SQUARE(x) ((x) * (X))
 
then I would use all-caps, because it is important to understand that it
is a macro.
scott@slp53.sl.home (Scott Lurndal): Nov 29 05:18PM

>On 28/11/2019 16:58, Frederick Gotham wrote:
 
>Once your LTO-optimised binary is stripped of all extra symbols, it will
>be very difficult to follow by examination of the object code.
 
Until you run it under QEMU and get a full instruction/register trace.
Vir Campestris <vir.campestris@invalid.invalid>: Nov 29 09:19PM

On 29/11/2019 18:58, Frederick Gotham wrote:
 
> If the Iranian government were to pay four hackers $120,000 each per year to figure out what my program is doing, I think they'd take about 5 or 6 weeks.
 
> Even if you were to give me the output of my own program, and then ask me to determine the state my program was in when it give that output, I think I would spend maybe 4-8 hours writing the program to do so.
 
> I think it would take the very best programmers-cum-hackers a few weeks to figure my program out.
 
Well, if it works ask yourself who is your competition?
 
It's not a new idea. If it works, someone must be doing it.
 
Andy
David Brown <david.brown@hesbynett.no>: Nov 29 11:21AM +0100

On 28/11/2019 16:58, Frederick Gotham wrote:
 
> I suppose another thing I could do is compile the 3rd party library
> with some sort of global setting that every function has the
> attribute "always_inline".
 
Obfustication like this does not work. If people have enough reason to
want to know what your program does, they will find out. It will take
them more time and effort, but they will manage it if they want.
 
But if you simply want to make it harder for casual hackers to know what
is going on in the code, don't mess around manually like this. Use
link-time optimisation, and -O3 optimisation. You might also like to
play with some of the parameters to encourage more inlining, cloning,
merging, etc. There are also a few more experimental code optimisation
options, or ones that change the language semantics, which can be
enabled explicitly (see the gcc documentation for details). And some,
like the "align" options, you might want to explicitly disable to make
code harder to follow.
 
The compiler can do a far better job of inlining, code-reordering,
unrolling, etc., than you can hope to manage.
 
Once your LTO-optimised binary is stripped of all extra symbols, it will
be very difficult to follow by examination of the object code.
Tim Rentsch <tr.17687@z991.linuxsc.com>: Nov 28 03:39PM -0800

> All objects *must* have complete types in C++ program:
> "A program is ill-formed if the definition of any object gives
> the object an incomplete type."
 
Not counting the misspelling of proper, there is nothing nonsensical
about it. Furthermore although the C++ standard doesn't use those
exact words, it does imply that the statement is true.
 
Incidentally, I think the word "bald" doesn't mean what you think it
means. The statement "the sun is shining today" could accurately,
even if perhaps confusingly, be termed a "bald statement".
Bonita Montero <Bonita.Montero@gmail.com>: Nov 27 07:18AM +0100


>> _MSC_VER wouldn't be a replacement for __cplusplus when you want to
>> be portable.
 
> Did I say anything will replace anything? ...
 
1. The discussion-context was __cplusplus
2. If you don't care for portability, checking _MSC_VER
could be a replacement for __cplusplus-checking.
Bonita Montero <Bonita.Montero@gmail.com>: Nov 27 05:45AM +0100

> of _MSC_VER in it since there is always some microsoft-specific
> weirdness to work around regardless if that /Zc:__cplusplus was set
> as compiler option or forgotten to.
 
_MSC_VER wouldn't be a replacement for __cplusplus when you want to
be portable.
Bonita Montero <Bonita.Montero@gmail.com>: Nov 27 05:49AM +0100

> get rid of WSAStartup and please, Linux, put sctp.h in a better
> place:
> https://github.com/Ebenezer-group/onwards/blob/master/src/cmw/tiers/cmwA.cc
 
Where's the problem? Use a C++ socket-lib because there are a
lot of differences between BSD-sockets and Windows sockets:
https://www.apriorit.com/dev-blog/221-crossplatform-linux-windows-sockets
Bonita Montero <Bonita.Montero@gmail.com>: Nov 27 08:11AM +0100

>> 1. The discussion-context was __cplusplus
 
> So what? It is standardized but non-portable in practice.
 
If you set the MSVC compiler-settings appropriately MSVC conforms.
And the other compilers are conformant anyway. So there's a way
to use __cplusplus across all compilers.
 
>> could be a replacement for __cplusplus-checking.
 
> Nonsense, it would be utterly useless check in majority of
> non-portable C++ code that I've seen.
 
I said that it wouldn't be portbale. But if you're fixed to MSVC you
could replace __cplusplus-checks with _MSC_VER-checks to different
values.
Tim Rentsch <tr.17687@z991.linuxsc.com>: Nov 28 12:46PM -0800


> I tend to agree. I use auto, but try to be careful so it won't be a
> problem when I revisit the code, like my duck typing exercises are in
> Python.
 
I don't have a lot of experience with "auto" in C++, but a fair
amount of experience with type inference (and not needing type
annotations in many cases) in other programming languages. I
don't have any hard and fast rule, but generally I find it works
well to give an explicit type annotation only in those cases
where it's important to know exactly what the type is. Probably
this rule carries over into C++ reasonably well, although the
two situations are not completely parallel. In particular, C++
doesn't have partial types, except maybe for arrays -- it's
pretty much all or nothing, either a completely specified type
or none at all; there is no way in C++ to say a type is "a list
of something, but I won't say what the something is". But I
think the general rule is still good in the C++ domain.
scott@slp53.sl.home (Scott Lurndal): Nov 29 10:04PM


>I compile this library to produce a static shared library. All of the objec=
>t files are gathered together into an archive (In Linux, this is a ".a" fil=
>e).
 
Careful with your terminology. An archive file is not a 'static shared library'.
 
Unix System V release 3 supported static shared libraries (which was a royal
pain because they all had to be statically linked at specific non-interfering
virtual addresses).
 
An archive (.a) is simply a 'folder' of object files.
 
The linker will access the archive when attempting to resolve external
symbols and will include any objects that contain such resolved external
symbols. All other objects in the archive will be ignored.
Taylor <wtholliday@gmail.com>: Dec 04 04:18PM -0800

On Wednesday, December 4, 2019 at 1:39:20 PM UTC-8, Alf P. Steinbach wrote:
 
> But now I fail to see, I don't remember, quite how it worked.
 
> As I see it the OP shouldn't assume that readers would be familiar with
> `overloaded`.
 
This is my point (2): that it's fancy and new and people might be confused by it. That's one reason I'm looking for other options :)
Taylor <wtholliday@gmail.com>: Dec 04 04:28PM -0800

On Wednesday, December 4, 2019 at 2:46:42 PM UTC-8, Öö Tiib wrote:
 
> Yeah I noticed that you both pass and return that variant as value
> in your examples. Are you sure that "value-oriented design" means
> that "always make copies when possible"?
 
It doesn't.
 
 
> It was you who said that people "might be baffled by the c++ fancyness"
> of your code. There are no performance, no robustness, no clarity,
> no readability ... what *is* the point?
 
Well, I don't claim to write perfect code :)
 
The point with that example was to be able to express things concisely. Performance doesn't matter that much (within reason of course).
 
I actually think it's fairly readable, but still a bit confusing for folks who aren't really up to date on "modern" c++.
 
> examples. ;) That immer seemed to be all for performance in concurrent
> processing. But just plain old "favor immutability" does not need
> special libraries for it so it did not make me to feel interested.
 
I'm not trying to be secretive. The immer containers offer memory efficient immutability, and other advantages. The author of Immer has some great talks which I would recommend watching:
 
https://youtu.be/_oBx_NbLghY
https://youtu.be/sPhpelUfu8Q
 
cheers
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Dec 05 05:13AM +0100

On 05.12.2019 01:18, Taylor wrote:
 
>> As I see it the OP shouldn't assume that readers would be familiar with
>> `overloaded`.
 
> This is my point (2): that it's fancy and new and people might be confused by it. That's one reason I'm looking for other options :)
 
 
I wouldn't describe myself as "new".
 
I see that the `overloaded` class is just a few lines of C++17 code and
is exposed on the cppreference.com page about `std::visit`.
 
You could/should simply have added a comment "For `overloaded`, see
<url: https://en.cppreference.com/w/cpp/utility/variant/visit#Example>".
 
Re the problem you're asking about, it seems clear that there is some
commonality of the classes that has not been factored out / abstracted,
but that the rest of the code relies on.
 
By stuffing everything into variants you're throwing away critical
static type information, replacing it with dynamic type information and
checking. A solution should involve not throwing away the static type
information, or at least throwing away less of it. And voilá.
 
 
- Alf
"Öö Tiib" <ootiib@hot.ee>: Dec 05 12:00AM -0800

On Thursday, 5 December 2019 02:28:14 UTC+2, Taylor wrote:
 
> I'm not trying to be secretive. The immer containers offer memory efficient immutability, and other advantages. The author of Immer has some great talks which I would recommend watching:
 
> https://youtu.be/_oBx_NbLghY
> https://youtu.be/sPhpelUfu8Q
 
Each tool has its use but hope of silver bullets makes you to sell snake
oil to yourself. You wrote "it only increases the size of Node by a
factor of two, which is totally fine".
 
You seemingly hope that immer wins the consequences: twice more storage
used per object and twice more cache misses somehow back? Again, there
can't be any magic, sorry.
 
That is why Boost.PolyCollection wins:
1) We get twice the memory efficiency compared with your original variant
and quadruple memory efficiency compared with your "factor of two" monster.
2) We get readability and maintainability of classical dynamic
polymorphism compared with tons of half-hidden switch-cases.
3) We get meaningful layout of data not some kind of flags that
tell what members do make sense and what members don't.
4) We get code-base with what work is possible to divide between contractors.
5) There are nothing bleeding edge fancy about all of it.
Manfred <invalid@add.invalid>: Dec 05 01:42AM +0100

On 12/4/19 8:16 PM, Manfred wrote:
 
Sorry, wrong line. Itis the /move/ assignment operator that should get a
non-const reference.
 
Daniel <danielaparker@gmail.com>: Dec 04 04:47PM -0800

On Wednesday, December 4, 2019 at 4:52:46 PM UTC-5, alexo wrote:
 
> your point 4)
 
> I added
 
> int& operator[] (int i) const { return data[i]; }
 
Should be
 
int operator[] (int i) const { return data[i]; }
 
Daniel
alexo <alelvb@inwind.it>: Dec 05 03:37AM +0100

Il 05/12/19 01:47, Daniel ha scritto:
 
> Should be
 
> int operator[] (int i) const { return data[i]; }
 
> Daniel
 
You are right, I'm learning from my mistakes.
Thank you
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: