Friday, September 25, 2020

Digest for comp.lang.c++@googlegroups.com - 25 updates in 1 topic

Andrey Tarasevich <andreytarasevich@hotmail.com>: Sep 24 11:29PM -0700

On 9/16/2020 12:16 PM, Mr Flibble wrote:
> Just submitted a VS2019 bug report (C++17 non-conformance):
 
> std::cout << a() << "," << b(); // a() is not sequenced before b()
 
> /Flibble
 
It is 2020 already and nobody seems to have gotten it quite right yet.
New C++17 sequencing rules remain largely un-/under-implemented in GCC
and Clang too.
 
#include <cstdint>
#include <iostream>
 
uint16_t foo(uint16_t abgr)
{
return (abgr ^= (abgr >> 8)) ^= (abgr << 8);
}
 
int main()
{
uint16_t tmp = 0xAABB;
std::cout << std::hex << tmp << " " << foo(tmp) << std::endl;
}
 
The result for 'foo(tmp)' is unambiguously defined: it shall be '0x1111'
and nothing else.
 
GCC produces '0xBB11', which is an instant fail. Clang produces the
correct result, but spews a completely unjustified sequencing warning
(albeit it seems that they finally got rid of it in version 10). MSVC++
produces the correct result and doesn't seem to complain.
 
--
Best regards,
Andrey Tarasevich
Ben Bacarisse <ben.usenet@bsb.me.uk>: Sep 25 03:45PM +0100

> }
 
> The result for 'foo(tmp)' is unambiguously defined: it shall be
> '0x1111' and nothing else.
 
I don't follow. The two shift operators are not sequenced in relation
to each other. The new C++17 rules for << and >> have no effect here as
neither operand has any side effects. Have I missed some broader rule
change?
 
--
Ben.
Juha Nieminen <nospam@thanks.invalid>: Sep 25 03:12PM

> It is 2020 already and nobody seems to have gotten it quite right yet.
 
Not getting something right about the C++17 standard is one thing.
How about, in 2020, not getting something right about the C++98
standard?
 
These two function declarations should be considered *different*
functions:
 
extern "C" using c_func = int(const void*, const void*);
extern "C++" using cpp_func = int(const void*, const void*)
 
These should be considered *different* overloads, ie. different
functions:
 
void foo(c_func*);
void foo(cpp_func*);
 
There's a bug report made in 2001 about gcc 2.97 about this issue,
which still hasn't been fixed in 2020 in gcc 10.
 
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=2316
 
Other compilers aren't much better about this.
Tim Rentsch <tr.17687@z991.linuxsc.com>: Sep 25 09:30AM -0700

> to each other. The new C++17 rules for << and >> have no effect here as
> neither operand has any side effects. Have I missed some broader rule
> change?
 
In C++17, assignment operators (including ^=, etc) specify that the
right operand is sequenced before the left operand. Hence the
outermost ^= causes the << to be sequenced before the inner ^=
expression.
Andrey Tarasevich <andreytarasevich@hotmail.com>: Sep 25 10:00AM -0700

On 9/25/2020 7:45 AM, Ben Bacarisse wrote:
> to each other. The new C++17 rules for << and >> have no effect here as
> neither operand has any side effects. Have I missed some broader rule
> change?
 
The key moment here is the new sequencing rules for assignment
operators, not for `<<`.
 
All assignment operators (including compound assignment) became very
tightly sequenced in C++17. Right-hand side is fully sequenced before
the left-hand size. The actual side effect (of assignment) takes place
before value-evaluation of the assignment-expression.
 
And this is what produces unambiguous sequencing of the shifts relative
to each other in the above example.
 
The '[]' operator is also sequenced now, and if I recall correctly this
is still glitchy in GCC.
 
--
Best regards,
Andrey Tarasevich
Leo <usenet@gkbrk.com>: Sep 17 06:12PM +0300

On 9/17/20 10:41 AM, Öö Tiib wrote:
> Swift is compiling to LLVM and performs similarly to C and C++.
 
In what world is Swift performing similarly to C and C++? Maybe badly
written C or Swift that no longer looks like Swift.
 
For 99% of the code mortals will come across, Swift performs much much
worse than C or C++.
Leo <usenet@gkbrk.com>: Sep 17 08:05PM +0300

On 9/17/20 7:16 PM, Öö Tiib wrote:
 
>> For 99% of the code mortals will come across, Swift performs much much
>> worse than C or C++.
 
> Cite?
 
How can I prove that Swift performs similarly to C, I don't even know
Swift. You need to write benchmarks so C/C++/Rust developers can fix the
performance bugs that make them as slow as Swift.
Juha Nieminen <nospam@thanks.invalid>: Sep 17 06:29PM


>> Cite?
 
> How can I prove that Swift performs similarly to C, I don't even know
> Swift.
 
You don't know Swift, but you know it performs much worse?
 
Based on what?
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.
Andrey Tarasevich <andreytarasevich@hotmail.com>: Sep 25 11:10AM -0700

On 9/16/2020 12:16 PM, Mr Flibble wrote:
> Just submitted a VS2019 bug report (C++17 non-conformance):
 
> std::cout << a() << "," << b(); // a() is not sequenced before b()
 
#include <iostream>
 
int main()
{
int i = 0;
std::cout << ++i << ++i << std::endl;
}
 
Compiling in GCC 10.2 with '-Wall -std=c++17'
 
warning: operation on 'i' may be undefined [-Wsequence-point]
std::cout << ++i << ++i << std::endl;
^~~
 
Compiling in Clang 10.0.1 with '-Wall -std=c++17'
 
warning: multiple unsequenced modifications to 'i' [-Wunsequenced]
std::cout << ++i << ++i << std::endl;
^ ~~
 
While both compilers produce the correct output, the above diagnostic
messages suggest that this is purely a coincidence. C++17 is still not
quite there in any of the current mainstream compilers. In many (if not
most) respects VS2019 looks well ahead of the pack.
 
--
Best regards,
Andrey Tarasevich
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.
"Chris M. Thomasson" <chris.m.thomasson.1@gmail.com>: Sep 17 08:56PM -0700

On 9/17/2020 6:06 PM, olcott wrote:
 
> It didn't occur to me until my other recent post that my use of printf
> over cout is not merely laziness, printf is simply better at formatted
> output.
 
Actually, using printf can sometimes be more "difficult" to use.
However, I still try to employ it when I can.
Juha Nieminen <nospam@thanks.invalid>: Sep 18 06:43AM

> It didn't occur to me until my other recent post that my use of printf
> over cout is not merely laziness, printf is simply better at formatted
> output.
 
Its major problem (besides not being type-safe) is that it's not extensible
with custom types and formatting.
 
Sure, you could write things like:
 
std::printf("a=%i, b=", a);
printMyCustomType(b);
std::printf(", c=%f\n", c);
 
but that's not very practical in all situations.
 
It's also not very generic:
 
template<typename T>
void debugPrint(const T& value)
{
std::printf("... uh ...", value); // ???
}
 
You could add overloads for every type supported by printf, but with
std::ostream you don't have to because it already defines those
overloads:
 
template<typename T>
void debugPrint(const T& value)
{
std::cout << value;
}
 
Also, a printf-based version would be more awkward when it comes to defining
formatting parameters. With a generic ostream-based version nothing stops you
from using its own formatting elements, like:
 
debugPrint("a=", std::hex, a);
 
(You can even implement that debugPrint() function in such a manner that it
restores the formatting flags of std::cout before it returns, so any
formatting changes don't linger afterwards.)
Juha Nieminen <nospam@thanks.invalid>: Sep 18 06:35AM

> For those types, reading from an iterator pair and writing to an
> output iterator would be no less performant, and provide
> more flexibility.
 
The iterator idiom is certainly very flexible and adds a lot of possibilities
that a "hard-coded" (so-to-speak) non-iterator based solution like
from_chars() and to_chars() can't offer.
 
For example, if the output would be specified with an iterator, you could
use something like a back_insert_iterator, or a ostream_iterator, or
whatever you want. Likewise for input, iterators wouldn't force you to have
the input string being in an actual array, but be eg. generated on the fly.
 
That being said, there could potentially be some efficiency benefits in
taking char*'s directly, rather than iterators: It opens the possibility
for the implementation to do things more efficiently than forward iterators
would allow, such as traversing the string backwards, or random-accessing
it. (You could make the iterator-based version require random access
iterators, but that would immediately cut off a lot of the benefits of
the iterator-based solution in the first place.)
 
> And support char8_t, char16_t and char32_t too.
 
I suppose the functions could be overloaded with versions taking those
types of pointers...
Bonita Montero <Bonita.Montero@gmail.com>: Sep 18 12:52PM +0200

> The problem was operator error: it helps if you change the compiler
> settings for the build configuration you are actually building.
 
Aside the compiler is actually right:
I think calling f2() and then f1() before cout without -std:c++ is
because the return of f2 is pushed first on the stack and then f1,
which fits to the topmost position which is required for the first
cout::operator << call.
Bonita Montero <Bonita.Montero@gmail.com>: Sep 18 01:39PM +0200

> because the return of f2 is pushed first on the stack and then f1,
> which fits to the topmost position which is required for the first
> cout::operator << call.
 
Sorry, I missed that operator << doesn't take a string-object.
There isn't even an overload that takes a string-reference. So
how does this work that you can output a string object to an
ostream ?
Bonita Montero <Bonita.Montero@gmail.com>: Sep 18 01:44PM +0200

I missed the global overloads.
Paavo Helde <eesnimi@osa.pri.ee>: Sep 18 03:42PM +0300

18.09.2020 09:43 Juha Nieminen kirjutas:
 
> std::printf("a=%i, b=", a);
> printMyCustomType(b);
> std::printf(", c=%f\n", c);
 
Sure it is extensible. The custom types must just be capable to produce
a string representation of themselves:
 
std::printf("a=%i, b=%s, c=%f", a, b.ToString().c_str(), c);
 
Considering that file output is slow anyway, constructing a
"superfluous" temporary string does not even affect performance.
Formatting parameters can be easily passed as arguments to ToString().
 
The only problem with std::printf() is the lack of type safety, but one
can create typesafe equivalents in C++, retaining the general printf
interface. There are many such solutions. I like my personal one which
overloads operator().
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Sep 18 02:47PM +0200

On 17.09.2020 09: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.
 
I prefer a common solution for basic string composition, writing the
above as e.g.
 
d_print( ""s
<< "The value of a is " << a << ", that of b is " << b
<< ", and str is "" << str << "".\n"
);
 
This way the function only needs a `const string_view&` parameter, or
the like, and the work of handling composition of umpteen args of
different types, does not have to be repeated in every such function.
 
I guess with the Fmt library in C++20 the specific syntax I use will
change, but same concept: centralize basic string composition,
centralize getter of filename and line number (well, that's almost
solved in C++20, all one needs is to leverage the standard library to
make an exception safe solution), and so on. Centralization, yay! Uh...
 
- Alf
Juha Nieminen <nospam@thanks.invalid>: Sep 18 01:56PM


> Sure it is extensible. The custom types must just be capable to produce
> a string representation of themselves:
 
> std::printf("a=%i, b=%s, c=%f", a, b.ToString().c_str(), c);
 
Extending std::ostream to support your custom type would usually not require
such temporary string buffers. Moreover, it grants you access to the
std::ostream object itself, giving you the option of *how* to output the
data (for example you could use std::ostream::write() instead of the regular
operator<<'s). With that scheme you propose you don't have access to the
FILE* where you are outputting, and thus you don't have, for example, the
option of using std::fwrite() if you so wanted.
 
Also, somewhat ironically, in some cases you would need to resort to
stringstreams in order to create the string to be printed.
 
> can create typesafe equivalents in C++, retaining the general printf
> interface. There are many such solutions. I like my personal one which
> overloads operator().
 
Not the only problem. I mentioned the other one: printf() is not generic
enough. You can't use it when the type of the value to print is abstracted
away (eg. it's a template type parameter). At least not even nearly as
easily as with std::ostream.
Richard Damon <Richard@Damon-Family.org>: Sep 18 10:20AM -0400

On 9/17/20 9:06 PM, olcott wrote:
 
> It didn't occur to me until my other recent post that my use of printf
> over cout is not merely laziness, printf is simply better at formatted
> output.
 
printf can be easier for fundamental types (of known type). It is very
hard to use for 'class' objects, particularly for polymorphic types. It
does give more concise formatting the fundamental types.
 
iostreams can be easier in generic code, as << will 'do the right thing'
for the type. Since it lets the type decide how to output itself, it
does make it harder to control the output at the point of use.
Melzzzzz <Melzzzzz@zzzzz.com>: Sep 18 03:16PM


> iostreams can be easier in generic code, as << will 'do the right thing'
> for the type. Since it lets the type decide how to output itself, it
> does make it harder to control the output at the point of use.
 
Isn't it that printf can be now implemented in type safe manner?
 
 
--
current job title: senior software engineer
skills: c++,c,rust,go,nim,haskell...
 
press any key to continue or any other to quit...
U ničemu ja ne uživam kao u svom statusu INVALIDA -- Zli Zec
Svi smo svedoci - oko 3 godine intenzivne propagande je dovoljno da jedan narod poludi -- Zli Zec
Na divljem zapadu i nije bilo tako puno nasilja, upravo zato jer su svi
bili naoruzani. -- Mladen Gogala
Paavo Helde <eesnimi@osa.pri.ee>: Sep 18 06:29PM +0300

18.09.2020 16:56 Juha Nieminen kirjutas:
> operator<<'s). With that scheme you propose you don't have access to the
> FILE* where you are outputting, and thus you don't have, for example, the
> option of using std::fwrite() if you so wanted.
 
I thought we were talking about formatted output, that's what fprintf()
and streams are all about. I'm curious, how many times have you used
std::ostream::write() in your operator<< ?
 
Also, I consider it a good thing to modularize the program. Why should
the code formatting the object content know or care about streams or
FILE* pointers? Moreover, this way my output may easily become broken if
the stream or FILE happens to use a strange locale.
 
> Also, somewhat ironically, in some cases you would need to resort to
> stringstreams in order to create the string to be printed.
 
So what? This is an implementation detail.
 
> enough. You can't use it when the type of the value to print is abstracted
> away (eg. it's a template type parameter). At least not even nearly as
> easily as with std::ostream.
 
How comes? If everything supports conversion to strings, it's trivial to
use in templates. Since C++11 we also have std::to_string() for
primitive types, so they could be easily incorporated as well if needed.
 
I mean, using C++ streams for formatted output is fine, I do not intend
to attack it in any way. I just objected the claim "printf-like
interface is not extensible with custom types and formatting".
Manfred <noname@add.invalid>: Sep 18 05:39PM +0200

On 9/17/2020 10:10 PM, Jorgen Grahn wrote:
 
> 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.
 
It's not just that. I have got customers that explicitly wanted
non-english UIs, but that kind of customers systematically want GUIs.
So, the point of localizing printf or std::cout is really non-existing.
It should have been left to application libraries, not in the standard,
same as GUI libraries.
 
> 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.
 
That's a good point.
 
> 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.
 
Even worse: most non-english keyboards still have a dot in the keypad
instead of a comma (although I have seen some having it in there), so
even for a French user typing 12345,67 is just painful.
 
Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk>: Sep 18 04:40PM +0100

On 18/09/2020 16:29, Paavo Helde wrote:
>> easily as with std::ostream.
 
> How comes? If everything supports conversion to strings, it's trivial to use in templates. Since C++11 we also have std::to_string() for primitive types, so they could be easily incorporated as well if needed.
 
> I mean, using C++ streams for formatted output is fine, I do not intend to attack it in any way. I just objected the claim "printf-like interface is not extensible with custom types and formatting".
 
Neither (f)printf nor iostreams are suitable for formatted output if such formatting is to include localization support; C++20 fmt should fix this inadequacy.
 
/Flibble
 
--
¬
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: