Wednesday, April 15, 2020

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

Tim Rentsch <tr.17687@z991.linuxsc.com>: Apr 15 03:47PM -0700


> https://www.infoworld.com/article/3535795/c-plus-plus-proposal-dismisses-backward-compatibility.html
 
> "Proposal to the C++ standards committee would give up backward and
> binary compatibility for safety and simplicity"
 
Reading the actual proposal reminds me of a comment made about
another programming language proposal from many many years ago:
"An exercise in group wishful thinking."
legalize+jeeves@mail.xmission.com (Richard): Apr 15 11:02PM

[Please do not mail me a copy of your followup]
 
Lynn McGuire <lynnmcguire5@gmail.com> spake the secret code
 
>https://www.infoworld.com/article/3535795/c-plus-plus-proposal-dismisses-backward-compatibility.html
 
>"Proposal to the C++ standards committee would give up backward and
>binary compatibility for safety and simplicity"
 
OK, finally had enough time to read through the cited Google paper on
refactoring and the proposal.
 
I don't know that I would summarize the proposal in the dire terms
cited above.
 
The things they are talking about jettisoning are along the likes of
trigaphs, which noone has sad to see disappear from the standard.
--
"The Direct3D Graphics Pipeline" free book <http://tinyurl.com/d3d-pipeline>
The Terminals Wiki <http://terminals-wiki.org>
The Computer Graphics Museum <http://computergraphicsmuseum.org>
Legalize Adulthood! (my blog) <http://legalizeadulthood.wordpress.com>
michaelwplde@gmail.com: Apr 14 05:40PM -0700

On Tuesday, April 14, 2020 at 6:03:40 AM UTC-4, Juha Nieminen wrote:
 
> for(auto i = 0; i < vec.size(); ++i)
 
> My response? "Don't use auto."
 
> My followup response? "Don't. Use. auto."
 
Great observations here. There's a time and a place for everything, and if you need to be explicit about the underlying type, do not use auto. If you do not want to depend on inferred type of a thing, do not use auto. For instance if you had to revise a vector or other collection from const to non-const, along those lines. Do not assume that the iterator would be the same. And so on.
 
Cholo Lennon <chololennon@hotmail.com>: Apr 14 10:25PM -0300

On 4/14/20 7:03 AM, Juha Nieminen wrote:
> situations (and in fact the language uses it to its advantage to abstract
> away types that the programmer doesn't need to care about, most prominently
> the exact type of lamdba functions).
 
Totally agree.
 
> probably even some experienced programmers) are shoving it *absolutely
> everywhere.* For reasons that I cannot really understand. Almost anywhere
> where 'auto' could be used, they will use it.
 
Well, C++ developers are going in the opposite direction of Python ones.
While Python has added data "type hints" in order to solve the mess that
Python code is, we started using auto in every place as you noted, which
complicates reading and tools, just to save some keystrokes. I know that
it's no fair to compare a static language with a dynamic one, but maybe
we should learn this lesson from Python.
 
 
 
> And what happens if the codes wants it to be something other than an int?
> I have seen abominations like
 
> auto i = (short)5;
 
OMG! :-O
 
 
> in general you really want to see the actual type you are expecting that
> function to return. (There are situations where you don't and shouldn't
> care about that type, but those tend to be rare.)
 
Yes, exactly, this is one of my concerns about auto in C++ (and in
Python without type hints), I need to know the return type in order to
undestand the code (or to operate with it). Sometimes is very easy to
follow the code, but in other cases is a nightmare.
 
 
> auto iter = myMap.begin();
 
> In most situations this is quite readable, understandable and not very
> error-prone.
 
I have the same rule
 
--
Cholo Lennon
Bs.As.
ARG
Juha Nieminen <nospam@thanks.invalid>: Apr 15 06:21AM

> On a minor quibble about what you say, it may be true that generally
> const methods 'shouldn't have side effects' (in the sense of 'I
> wouldn't do that'), but that is not a requirement of the standard.
 
That's why I said (trying to paraphrase what I believe Herb Shutter meant)
"in well-designed code".
 
Generally the standard doesn't take a stance on code quality.
Jorgen Grahn <grahn+nntp@snipabacken.se>: Apr 15 07:34AM

On Tue, 2020-04-14, Daniel P wrote:
...
> "logical" state of the object remains the same. Not something the compiler
> can use to optimize or diagnose. And of limited value for reasoning about
> code.
 
That value is limited (like most values) but IMO great. It's one of
the best things about C and C++.
 
/Jorgen
 
--
// Jorgen Grahn <grahn@ Oo o. . .
\X/ snipabacken.se> O o .
Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk>: Apr 15 12:13PM +0100

On 14/04/2020 11:03, Juha Nieminen wrote:
> auto iter = myMap.begin();
 
> In most situations this is quite readable, understandable and not very
> error-prone.
 
auto is great; use almost everywhere! Saying that a construct such as 42i16 or 42u16 would be nice for integer literals; can we have that with the user defined literals?
 
/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."
Ned Latham <nedlatham@woden.valhalla.oz>: Apr 15 06:35AM -0500

Mr Flibble wrote:
 
----snip----
 
> auto is great; use almost everywhere! Saying that a construct such as
> 42i16 or 42u16 would be nice for integer literals; can we have that
> with the user defined literals?
 
They have to be interpreted for computation. So you might as well
define them as strings and gain the compiler checking.
David Brown <david.brown@hesbynett.no>: Apr 15 02:27PM +0200

On 15/04/2020 13:13, Mr Flibble wrote:
 
> auto is great; use almost everywhere! Saying that a construct such as
> 42i16 or 42u16 would be nice for integer literals; can we have that with
> the user defined literals?
 
Sure:
 
#include <stdint.h>
 
int16_t operator"" i16(unsigned long long x) {
return x;
}
 
uint16_t operator"" u16(unsigned long long x) {
return x;
}
 
I guess it would be easy to have these standardised, if someone thinks
they would be useful enough to justify the effort in all the
documentation and bureaucracy involved (which would far outweigh the
coding effort).
jacobnavia <jacob@jacob.remcomp.fr>: Apr 15 02:59PM +0200

Le 15/04/2020 à 14:27, David Brown a écrit :
 
> int16_t operator"" i16(unsigned long long x) {
>     return x;
> }
 
int16_t operator"" i16(long long x) {
if (x < 32768 && x >= -32767) ) return x;
throw("overflow");
}
 
Note the long long and NOT unsigned long long since the result is signed
 
 
> uint16_t operator"" u16(unsigned long long x) {
>     return x;
> }
 
uint16_t operator"" i16(long long x) {
if (x < 65536 ) ) return x;
throw("overflow");
}
 
Isn't error checking an essential part of writing code?
Or did I miss something? (My C++ is not very good)
David Brown <david.brown@hesbynett.no>: Apr 15 05:03PM +0200

On 15/04/2020 14:59, jacobnavia wrote:
>      throw("overflow");
> }
 
> Note the long long and NOT unsigned long long since the result is signed
 
No.
 
You can't have "long long" as the parameter. (I tested my code - did you?)
 
Although it might seem like the minus sign is part of the integer
literal, it is not. "-1234" is a unary minus operator and an integer
literal 1234. "-1234i16" is a unary minus operator applied to the
result of operator"" i16(1234).
 
Thus the parameter must always be unsigned long long.
 
Having a "throw" looks nice, but has the disadvantage of being a
run-time check, when you want a compile-time check.
 
With C++20 "consteval", it's easy - a user-defined literal can be
declared "consteval", and then the throw turns into a compile-time error.
 
Getting a result that will work as desired for -32768_i16 through to
32767_i16, but give compile-term errors outside that range, is not easy.
 
> }
 
> Isn't error checking an essential part of writing code?
> Or did I miss something? (My C++ is not very good)
 
The ideal is compile-time errors for things like this (since we are
talking about literals, they are known at compile time).
 
The best I could come up with is by using C++ "consteval" and a proxy class:
 
#include <stdint.h>
 
class int16_t_proxy {
private:
int32_t x_;
constexpr int16_t_proxy(int32_t x) : x_(x) {};
public:
friend consteval int16_t_proxy operator"" _i16(unsigned long long x);
consteval int16_t_proxy operator-() {
return -x_;
}
consteval operator int16_t() {
if (x_ > 32767) throw "overflow";
return x_;
};
};
 
consteval int16_t_proxy operator"" _i16(unsigned long long x) {
if (x > 32768) throw "overflow";
return x;
}
 
int16_t xx1() {
return 32767_i16;
}
 
int16_t xx2() {
return -32768_i16;
}
 
 
Unfortunately, compilers don't seem to be ready for this. Clang trunk
uses a run-time exception for "32768_i16", though it correctly gives a
compile-time error for bigger values. I.e., it does not allow a throw
in the consteval operator""_i16(), but it /does/ allow it in the
consteval operator int16_t(). I believe clang is wrong here.
 
And while gcc trunk /does/ give a compile time error on 32768_i16, it
gives an internal compiler error for -32768_i16 (and any other use of
the operator-()).
 
(This is testing with <https://godbolt.org>.)
 
 
If my code is wrong, or my interpretation of clang and gcc is wrong, or
there are improvements to make in the code (other than obvious things
like naming) or other approaches, I would be glad to hear from others.
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Apr 15 08:58PM +0200

On 15.04.2020 17:03, David Brown wrote:
> literal, it is not.  "-1234" is a unary minus operator and an integer
> literal 1234.  "-1234i16" is a unary minus operator applied to the
> result of operator"" i16(1234).
 
 
Oh dear, that seems to imply that the usual arithmetic conversions will
kick in, making -42i16 produce an `int`?
 
Gah!
 
 
> [snip]
 
- Alf
James Kuyper <jameskuyper@alumni.caltech.edu>: Apr 15 03:54PM -0400

On 4/15/20 2:58 PM, Alf P. Steinbach wrote:
> On 15.04.2020 17:03, David Brown wrote:
>> On 15/04/2020 14:59, jacobnavia wrote:
>>> Le 15/04/2020 à 14:27, David Brown a écrit :
...
>> result of operator"" i16(1234).
 
> Oh dear, that seems to imply that the usual arithmetic conversions will
> kick in, making -42i16 produce an `int`?
 
The usual arithmetic conversions only apply to binary operators, not
unary '-'. You may be thinking of the integral promotions. It will be
promoted to int if the integer conversion rank of int16_t is less than
that of int and "int can represent all the values of" int16_t (7.6p1).
 
Do you see that as problematic?
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Apr 15 10:17PM +0200

On 15.04.2020 21:54, James Kuyper wrote:
> promoted to int if the integer conversion rank of int16_t is less than
> that of int and "int can represent all the values of" int16_t (7.6p1).
 
> Do you see that as problematic?
 
Yes, it is.
 
- Alf
Daniel P <danielaparker@gmail.com>: Apr 15 01:50PM -0700

On Wednesday, April 15, 2020 at 7:13:46 AM UTC-4, Mr Flibble wrote:
 
> auto is great; use almost everywhere!
 
Just not here
 
Matrix2d mat;
mat << 1, 2,
3, 4;
Vector2d u(-1,1), v(2,0);
std::cout << "Here is mat*mat:\n" << mat*mat << std::endl;
std::cout << "Here is mat*u:\n" << mat*u << std::endl;
std::cout << "Here is u^T*mat:\n" << u.transpose()*mat << std::endl;
std::cout << "Here is u^T*v:\n" << u.transpose()*v << std::endl;
std::cout << "Here is u*v^T:\n" << u*v.transpose() << std::endl;
std::cout << "Let's multiply mat by itself" << std::endl;
mat = mat*mat;
Daniel P <danielaparker@gmail.com>: Apr 15 01:59PM -0700

On Wednesday, April 15, 2020 at 7:13:46 AM UTC-4, Mr Flibble wrote:
 
> auto is great; use almost everywhere!
 
Except:
 
Eigen::Matrix2d mat;
mat << 1, 2,
3, 4;
Eigen::Matrix2d mat = mat*mat; // NOT HERE
 
and
 
std::vector<bool> v{true, false};
bool val = v[1]; // NOT HERE
 
and
 
xt::xarray<double> arr1
{{1.0, 2.0, 3.0},
{2.0, 5.0, 7.0},
{2.0, 5.0, 7.0}};
 
xt::xarray<double> arr2 = arr1 + arr2; // NOT HERE
 
etc.
 
Daniel
James Kuyper <jameskuyper@alumni.caltech.edu>: Apr 15 05:03PM -0400

On 4/15/20 4:17 PM, Alf P. Steinbach wrote:
>> that of int and "int can represent all the values of" int16_t (7.6p1).
 
>> Do you see that as problematic?
 
> Yes, it is.
 
Could you explain that a little more? Specifically, could you give an
example of how it could cause problems?
 
I've worked with C/C++ for 40 years now. In both of those languages, the
integral promotions (in C, they're called integer promotions) apply to
any integer type with an integer conversion rank less than that of int
for which all of it's values can be represented as an 'int'. That is
guaranteed to be true of signed char, and short. On most common systems
today, they also apply to char, unsigned char, unsigned short,
[u]int8_t, and [u]int16_t, [u]int_least8_t, [u]int_least16_t,
[u]int_fast8_t, and [u]intfast16_t. I've used systems where 'int' is a
64-bit type, on which [u]int32_t, [u]int_least32_t and [u]int_fast32_t
are also subject to promotion. And while those promotions do
occasionally cause problems, they're very far from being the biggest,
most common, or most difficult to deal with problems I run into.
 
One key reason why they tend to be unproblematic is that the integral
promotions, as a matter of deliberate design, never change the value of
an expression, only it's type.
Louis Krupp <lkrupp@invalid.pssw.com.invalid>: Apr 15 04:46PM -0600

On 4/14/2020 6:35 AM, Juha Nieminen wrote:
> simultaneously without any misbehavior happening. In other words,
> the function is "thread-safe" with itself, ie. in the context of
> being called from multiple threads at the same time.)
 
As I understand it, reentrancy is an issue even when there's only one
thread. Some links:
 
https://www.geeksforgeeks.org/reentrant-function/
 
https://deadbeef.me/2017/09/reentrant-threadsafe
 
An example of a function that is thread-safe but not necessarily
reentrant would be one that writes and reads a thread-local variable
while calling itself.
 
Louis
legalize+jeeves@mail.xmission.com (Richard): Apr 15 04:37PM

[Please do not mail me a copy of your followup]
 
Keith Thompson <Keith.S.Thompson+u@gmail.com> spake the secret code
 
>But the most helpful thing you could provide is a complete
>self-contained program that exhibits the problem.
 
FYI, github gists are a great way to share a small piece of code like
this.
 
Or even better, a link to an example in compiler explorer.
--
"The Direct3D Graphics Pipeline" free book <http://tinyurl.com/d3d-pipeline>
The Terminals Wiki <http://terminals-wiki.org>
The Computer Graphics Museum <http://computergraphicsmuseum.org>
Legalize Adulthood! (my blog) <http://legalizeadulthood.wordpress.com>
legalize+jeeves@mail.xmission.com (Richard): Apr 15 04:39PM

[Please do not mail me a copy of your followup]
 
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com> spake the secret code
>>> You should report this through the proper Microsoft channels.
 
>> Where it will go directly to /dev/null.
 
>That's not my experience.
 
It depends on what kind of bugs you file. I've filed many bugs that
get sent to some QA team in China that is clearly being measured by
how many bugs they close, not how many issues are resolved to the
customer's satisfaction. They are very quick to say "can't reproduce,
close" and they don't even follow the reproducing steps I write in the
bug.
 
This was my experience in the last few years; perhaps recently they've
improved the situation. I still file bugs, but I don't expect them to
get fixed.
--
"The Direct3D Graphics Pipeline" free book <http://tinyurl.com/d3d-pipeline>
The Terminals Wiki <http://terminals-wiki.org>
The Computer Graphics Museum <http://computergraphicsmuseum.org>
Legalize Adulthood! (my blog) <http://legalizeadulthood.wordpress.com>
Keith Thompson <Keith.S.Thompson+u@gmail.com>: Apr 15 01:23PM -0700


> FYI, github gists are a great way to share a small piece of code like
> this.
 
> Or even better, a link to an example in compiler explorer.
 
Sure, but in this particular case the code snippet was short enough
that I expect a full example would reasonably fit into a post.
A link to a web site might not necessarily outlive the article.
 
--
Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
Working, but not speaking, for Philips Healthcare
void Void(void) { Void(); } /* The recursive call of the void */
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: