Thursday, September 17, 2020

Digest for comp.lang.c++@googlegroups.com - 11 updates in 2 topics

Keith Thompson <Keith.S.Thompson+u@gmail.com>: Sep 17 12:20PM -0700

> On Thursday, 17 September 2020 18:26:41 UTC+3, daniel...@gmail.com wrote:
 
>> Regarding characters, C++ has char, signed char, unsigned char, char8_t,
>> char16_t, char32_t, and wchar. And C++ has the notion of generics.
 
wchar_t, not wchar.
 
> Some are historically there but newer ones seem to be added to
> make things more confused. All of those besides char are anyway
> less useful than char and nothing helps it.
 
unsigned char is very useful for accessing raw memory.
 
wchar_t is vital for dealing with wide character data on Windows.
(I *wish* Windows used UTF-8 rather than UTF-16, but it doesn't.)
 
[...]
 
--
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 */
Ben Bacarisse <ben.usenet@bsb.me.uk>: Sep 17 09:01PM +0100


> If functions don't have side effect, then no problem. In haskell almost
> evry function is pure, that is you can't predict when they are evaluated
> ;)
 
But, but, but! Haskell is a lazy language, and guaranteed to be so, so
you can often predict when a function /won't/ be evaluated! For
example, there must be no IO resulting from this definition
 
x = [putStrLn "a", putStrLn "b"]
 
A more extreme example would be
 
y = last [1..]
 
which defines y to be the "last" positive integer. No problem. You can
define many other things using z. What you can't do is inspect any of
them.
 
--
Ben.
"Öö Tiib" <ootiib@hot.ee>: Sep 17 01:03PM -0700

On Thursday, 17 September 2020 22:21:11 UTC+3, Keith Thompson wrote:
> > make things more confused. All of those besides char are anyway
> > less useful than char and nothing helps it.
 
> unsigned char is very useful for accessing raw memory.
 
Yes, I meant for text. For raw bits/bytes I actually prefer to use
it under name uint8_t as it is shorter to write, has single word
identifier and ensures that either the resulting bytes are platform
agnostic or the code does not compile.
 
> wchar_t is vital for dealing with wide character data on Windows.
> (I *wish* Windows used UTF-8 rather than UTF-16, but it doesn't.)
 
Yes, same with Qt. Translating between UTF-16LE and UTF-8 is
fortunately trivial in module interface. Yes, sad, I like
Windows somewhat. May be one day Mr Flibble's neoGFX saves us
from Qt. ;)
Jorgen Grahn <grahn+nntp@snipabacken.se>: Sep 17 08:10PM

On Thu, 2020-09-17, Juha Nieminen wrote:
 
> I don't really understand why the C++ standard library (and possibly the
> C standard library, where C++ "inherited" it) decided to go with those
> stupid localization complications.
 
Also, I've never (at home or at work) had any use for any of it.
Customers have never wanted a user interface not in English, and so
on.
 
Maybe it was an idea that sounded like a good idea in the 1980s.
Or maybe it /is/ a good idea in countries where people don't accept
English as the lingua franca in technology, e.g. France.
 
To be honest, there is one feature I want, too: I want sorting of
strings to take my national characters into account ("Öö" would sort
last). I can get that with LC_COLLATE="sv_SE". But then I get
things I probably /don't/ want too, such as case-insensitive sort.
It's a blunt instrument.
 
> character used as the decimal point depends on the locale), which made
> it completely useless for my purposes (because I wanted to parse
> floating point values in a fixed format).
 
Here is another bluntness: sv_SE implements the old 12.345,67 syntax
for saying 12345.67, but people are just as likely to input 12345.67,
especially if they're programmers, or have any international contacts
at all[1]. So you can't always use it in a localized user interface,
either. Not without annoying people.
 
/Jorgen
 
[1] E.g. by being on the Internet.
 
--
// Jorgen Grahn <grahn@ Oo o. . .
\X/ snipabacken.se> O o .
"daniel...@gmail.com" <danielaparker@gmail.com>: Sep 17 01:34PM -0700

On Thursday, September 17, 2020 at 2:46:07 PM UTC-4, Öö Tiib wrote:
 
> Therefore performance features from_chars and to_chars are
> doing the obvious ... namely reading and writing chars in most
> performant containers of text.
 
For those types, reading from an iterator pair and writing to an
output iterator would be no less performant, and provide
more flexibility. And support char8_t, char16_t and char32_t too.
Limiting to char* simply increases the likelihood
that a temporary buffer will be needed, requiring copying
from the source or to the destination. With iterators,
they couldn't have made the same guarantee of
non-throwing, but the caller can make that decision.
 
Daniel
"Öö Tiib" <ootiib@hot.ee>: Sep 17 02:49PM -0700

> from the source or to the destination. With iterators,
> they couldn't have made the same guarantee of
> non-throwing, but the caller can make that decision.
 
How you implement it in generic manner? Reverse engineer back
to type and then have lookup tables for each of 'a', u8'a',
L'a', u'a' and U'a' to compare with 'a' when base is 11?
"daniel...@gmail.com" <danielaparker@gmail.com>: Sep 17 03:18PM -0700

On Thursday, September 17, 2020 at 5:50:07 PM UTC-4, Öö Tiib wrote:
> How you implement it in generic manner? Reverse engineer back
> to type and then have lookup tables for each of 'a', u8'a',
> L'a', u'a' and U'a' to compare with 'a' when base is 11?
 
I don't understand your point. The characters that from_chars
and to_chars support, 0-9, a..z (for the integer conversions in
different bases), '.', a..f (hex floating point), '-', 'e', have the same
numerical values in ansii, UTF-8, UTF-16, and UTF-32. There is
no need to look up anything.
 
Daniel
Ian Collins <ian-news@hotmail.com>: Sep 18 11:00AM +1200

On 17/09/2020 19:11, Juha Nieminen wrote:
 
> Implementing such a function is perfectly possible, even easy. But
> it's easy only if you use std::cout in its implementation. Not so easy
> if you wanted to use std::printf instead.
 
That is how I have updated our project logging; from a user's
perspective, the log print is the same as python3 print :)
 
--
Ian.
Keith Thompson <Keith.S.Thompson+u@gmail.com>: Sep 17 12:17PM -0700


> typedef int (*FuncPtr)(int);
 
> Now 'FuncPtr' is a type alias for a function pointer of that type.
> This explains the sometimes obscure-looking typedef syntax.
 
And the reason this works is that "typedef" is syntactically treated as
a storage-class specifier, even though it doesn't specify a storage
class. The other storage-class specifiers are:
extern
static
_Thread_local
auto
register
 
So another way to do this is to write a definition of a static
variable and replace the keyword "static" by "typedef".
 
(This also means that the placement of the keyword is flexible. You
*could* write "int static AnInteger;" or "int typedef AnInteger;".
But don't do that. Aside from being ugly and confusing, "The
placement of a storage-class specifier other than at the beginning
of the declaration specifiers in a declaration is an obsolescent
feature".)
 
Historically, early versions of C didn't have typedef. When it
was added, it was necessary to do so in a way that didn't break
existing code, so the existing syntax for storage-class specifiers
was borrowed.
 
--
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 */
Bart <bc@freeuk.com>: Sep 17 09:49PM +0100

On 17/09/2020 19:27, Juha Nieminen wrote:
 
> int (*funcPtr)(int);
 
> Now just slap 'typedef' in front of it, and you're done:
 
> typedef int (*FuncPtr)(int);
 
It doesn't need to be in front:
 
int typedef (*FuncPtr)(int);
 
will work too. The typedef can go anywhere before any "*" or variable
name or "(".
Keith Thompson <Keith.S.Thompson+u@gmail.com>: Sep 17 03:52PM -0700


> int typedef (*FuncPtr)(int);
 
> will work too. The typedef can go anywhere before any "*" or variable
> name or "(".
 
Yes, but as I mentioned in my own followup, this is a bad idea.
 
Though the syntax doesn't enforce it, it's conventional to put any
storage-class specifier (including "typedef") at the beginning
of a declaration. In fact the ability to put it anywhere else
is considered obsolescent, which is basically a warning that it
could be removed in a future standard. (The latest C2X draft has
not done so.)
 
N1570 and N2479:
 
6.11.5 Storage-class specifiers
 
The placement of a storage-class specifier other than at the
beginning of the declaration specifiers in a declaration is an
obsolescent feature.
 
--
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: