Tuesday, June 1, 2021

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

Christian Gollwitzer <auriocus@gmx.de>: May 27 07:50AM +0200

Am 26.05.21 um 20:32 schrieb Lynn McGuire: - Alf
> __int64 outputFileLength = _ftelli64 (pOutputFile) + 42;  // give it
> some slop
> int outputFileLengthInt = (int) outputFileLength;
 
...and here you restrict it to 2GB again, or worse, retrieve a negative
file size for sizes between 2GB and 4GB.
 
 
To prepare for a 64bit move, you should replace all size variables with
size_t for unsigned or ptrdiff_t for signed. That will correspond to a
32bit integer in 32 bit and a 64 bit integer in 64 bit.
 
Christian
David Brown <david.brown@hesbynett.no>: Jun 01 08:29AM +0200

On 31/05/2021 23:43, Keith Thompson wrote:
> Both of them destroy the point of intmax_t, providing a type that's
> guaranteed to be the longest integer type. Should intmax_t be
> deprecated?
 
In my opinion, yes - it should be deprecated. But of course you'd want
to check with people who actually use it, to see why the use it and
whether there are better alternatives.
 
 
> And since, as far as I've been able to tell, no implementation
> supports extended integer types, I wonder if they should be
> reconsidered.
 
Maybe it would be worth reconsidering exactly what the definition of
"integer type" should be in the C and C++ standards (keeping both
languages in sync here is, I think, important). I'd like to see
intmax_t removed and the definition of "integer type" modified such that
gcc's __int128 /is/ an extended integer type. After all, people use it
as though it were, and assume it is.
Bo Persson <bo@bo-persson.se>: Jun 01 01:59PM +0200


> Yes. "Give me the biggest integer type there is" is not a reasonable
> thing to ask for, in any code that is intended to be portable across platforms
> or over time on the same platform. You may as well have intwhatever_t.
 
The problem is that we in general don't know what "whatever" is. At the
time when intmax_t was introduced, at least in C there were
implementations with 36 bit ints and 72-bit longs. So just using int64_t
would not be portable.
Bo Persson <bo@bo-persson.se>: Jun 01 02:05PM +0200

On 2021-06-01 at 08:29, David Brown wrote:
 
> In my opinion, yes - it should be deprecated. But of course you'd want
> to check with people who actually use it, to see why the use it and
> whether there are better alternatives.
 
Nowadays it is very likely long long, for "reasonably wide integer
type". But that hasn't always been available.
 
 
> intmax_t removed and the definition of "integer type" modified such that
> gcc's __int128 /is/ an extended integer type. After all, people use it
> as though it were, and assume it is.
 
And it really *is*, except for the documentation saying "integer type
extension" (and not "extended integer type"), only to avoid the intmax_t
problem.
David Brown <david.brown@hesbynett.no>: Jun 01 03:55PM +0200

On 01/06/2021 13:59, Bo Persson wrote:
> time when intmax_t was introduced, at least in C there were
> implementations with 36 bit ints and 72-bit longs. So just using int64_t
> would not be portable.
 
Have there ever been C99 compilers for 36-bit int machines? Were there
even conforming C90 compilers?
 
AFAIK (and I fully admit my knowledge may be lacking), the only systems
that made it past the 1980's which did not have two's complement signed
integers with 8-bit bytes and power-of-two sized integer types are some
DSPs and other niche embedded devices (for which no one would use an
integer type without knowing /exactly/ how big it is), and
Burroughs/Unisys systems for legacy compatibility.
 
My suggestion would be to lock intmax_t to "long long", which would keep
compatibility here (including for systems that have 128-bit long long,
if there are any other than a hypothetical RISC-V version).
David Brown <david.brown@hesbynett.no>: Jun 01 03:58PM +0200

On 01/06/2021 14:05, Bo Persson wrote:
 
> And it really *is*, except for the documentation saying "integer type
> extension" (and not "extended integer type"), only to avoid the intmax_t
> problem.
 
There is also no way to make constant literals of __int128, nor is there
support for printf and a wide variety of the builtin functions, and
standard library functions, and other bits and pieces. It's fine for
basic usage, but missing many features of int64_t and other sized
integer types. (I'm not complaining, just noting.)
James Kuyper <jameskuyper@alumni.caltech.edu>: Jun 01 11:33AM -0400

On 6/1/21 9:58 AM, David Brown wrote:
> On 01/06/2021 14:05, Bo Persson wrote:
>> On 2021-06-01 at 08:29, David Brown wrote:
...
> standard library functions, and other bits and pieces. It's fine for
> basic usage, but missing many features of int64_t and other sized
> integer types. (I'm not complaining, just noting.)
 
If they changed their documentation to identify __int128_t as an
extended integer type, then they would be required to support int128_t,
along with all of the corresponding features of <cinttypes> and
<cstdint>, which would address that issue.
Manfred <noname@add.invalid>: Jun 01 06:00PM +0200

On 6/1/2021 3:55 PM, David Brown wrote:
 
> My suggestion would be to lock intmax_t to "long long", which would keep
> compatibility here (including for systems that have 128-bit long long,
> if there are any other than a hypothetical RISC-V version).
 
I think this would be problematic as well, or at least useless and
confusing.
The idea for intmax_t is to give a standard name to the widest integer
type that is available, which is by definition implementation defined.
Having intmax_t an alias for "long long" would change its meaning to the
widest /standard/ integer type defined by the standard itself - a
useless repetition (we have "long long" for that), and confusing too,
given its change in meaning.
 
As far as I understand the purpose for intmax_t is to allow for (sort
of) 'standard' prototypes of functions like imaxabs, imaxdiv, strtoimax,
etc that are supposed to operate on larger integer types - these are the
only functions that take this kind of arguments.
The confusing part is that all of these facilities are implementation
dependent, so even if they are part of the standard they are /not/
portable, meaning that the programmer is supposed (the way I see it) to
use them under the guard of appropriate preprocessor directives.
 
The use for them is to allow the programmer to use some optimized
routines for larger types, if available.
 
For example, in case operations like ldiv are needed on 128 bit
integers, then IF the implementation supports 128 bit intmax_t then
imaxdiv can be a better choice rather than implementing your own routine
- note that /IF/ is the keyword here, that should map directly to
appropriate #if directives.
 
It's most probably somewhat a niche field of use (possibly growing due
to the diffuse demand for cryptography), or meant for applications that
are supposed to be run on hardware that is known to support the
appropriate types, so that the #if directives can be as simple as
denying compilation for implementations that don't have a wide enough
intmax_t.
 
My 2c.
David Brown <david.brown@hesbynett.no>: Jun 01 07:15PM +0200

On 01/06/2021 18:00, Manfred wrote:
> widest /standard/ integer type defined by the standard itself - a
> useless repetition (we have "long long" for that), and confusing too,
> given its change in meaning.
 
Yes, that is all true. The point is not to find another useful purpose
for intmax_t - the point is to get rid of it, marking it as deprecated,
but to do so in a way that won't break existing code.
 
I am at a loss to understand why anyone would have a use for intmax_t in
the first place. When would you want an integer type whose sole
characteristic is "big" ? To me, it is logical to want a type that is
at least N bits, or exactly N bits. These requirements are covered by
the normal "short", "int", "long" and "long long" types, or - better for
my use, but not necessarily other people's - the <stdint.h> fixed size
types. "intmax_t" gives you absolutely /nothing/ that "long long" does not.
 
Given that there are, as far as we know, no implementations where
intmax_t does not correspond directly to "long long", I would like to
see "intmax_t" be dropped to the maximum extent allowable by backwards
compatibility.
 
> use them under the guard of appropriate preprocessor directives.
 
> The use for them is to allow the programmer to use some optimized
> routines for larger types, if available.
 
But they don't allow that. If you are trying to make optimised routines
for larger types, you need to know your sizes - you either use
implementation extensions (like __int128), or fixed size types, or if
you need maximal portability, you use "int_fast64_t".
 
> imaxdiv can be a better choice rather than implementing your own routine
> - note that /IF/ is the keyword here, that should map directly to
> appropriate #if directives.
 
The situation we have now is that on a compiler like gcc you can get
128-bit division using __int128, but /not/ using intmax_t. It is a
useless type.
 
Keith Thompson <Keith.S.Thompson+u@gmail.com>: Jun 01 10:52AM -0700

> extended integer type, then they would be required to support int128_t,
> along with all of the corresponding features of <cinttypes> and
> <cstdint>, which would address that issue.
 
*And* they'd have to make intmax_t 128 bits, which would cause more
problems.
 
--
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 */
Bonita Montero <Bonita.Montero@gmail.com>: Jun 01 06:14AM +0200

>> and address the three variables as [reg+a], [reg+b] and [reg+c].
 
> No they have not. You may assign any other function pointer to the
> function type f later.
 
Of course they have because the stack has a fixed layout. And even
more: you may put _no_ pointer inside the lambda-object since it has
fixed place inside the stack and you could address all other objects
at relative addresses to that address.
Bonita Montero <Bonita.Montero@gmail.com>: Jun 01 06:15AM +0200

>> You're so ultimately stupid.
 
> Hint:  an ad hominem reply means you have lost the debate
 
No, it means it doesn't make sense do debate sinnce the
person you're discussing with doesn't understand anything.
Juha Nieminen <nospam@thanks.invalid>: Jun 01 07:10AM

> On 5/30/2021 9:16 PM, Bonita Montero wrote:
>> You're so ultimately stupid.
 
> Hint: an ad hominem reply means you have lost the debate
 
That's not an ad hominem. Insulting someone is not an ad hominem. That's
a surprisingly (and sadly) common misconception.
 
An ad hominem argument is arguing against the claim made by someone by
alluding to something objectionable about that person, which has nothing
to do with the claim. Like, for example, "he has committed this heinous
crime, therefore what he's claiming about this mathematical proof is
not to be trusted" (not with those exact words, of course, but as the
fundamental idea). In the current day and age perhaps even more commonly
"he holds these political beliefs, therefore what he's saying (about
this thing completely unrelated to politics) is not to be trusted".
 
"An attack to the person" does not mean "being aggressive towards the
person (eg. with insults or swearwords)". It means "trying to discredit
what the person is saying by discrediting the reputation of the person".
 
"Argumentum ad hominem" could, perhaps, be more accurately translated
as "argument by attacking the reputation of the person".
Ben Bacarisse <ben.usenet@bsb.me.uk>: Jun 01 10:29AM +0100

> what the person is saying by discrediting the reputation of the person".
 
> "Argumentum ad hominem" could, perhaps, be more accurately translated
> as "argument by attacking the reputation of the person".
 
The attack is on the argument via the character of the person making it.
 
--
Ben.
Manfred <noname@add.invalid>: Jun 01 02:51PM +0200

On 6/1/2021 6:15 AM, Bonita Montero wrote:
 
>> Hint:  an ad hominem reply means you have lost the debate
 
> No, it means it doesn't make sense do debate sinnce the
> person you're discussing with doesn't understand anything.
 
One of you two doesn't understand what the other is saying, sure.
The fact is that it is not the one that you think the one that is defective.
 
Still, it doesn't make sense to keep debating this way - at least you
got this part right.
Bonita Montero <Bonita.Montero@gmail.com>: Jun 01 03:24PM +0200

> One of you two doesn't understand what the other is saying, sure.
 
It's all related to this:
 
| If some optimization in some compiler of some feature is missing and
| so your resulting program is slow then you should write less garbage
| code that compiler can't optimize. Or you can take source code of
| compiler, implement the optimization you need and put up a pull
| request.
 
Is this qualified arguing ?
Öö Tiib's postings are mostly nonsense.
"Öö Tiib" <ootiib@hot.ee>: Jun 01 09:04AM -0700

On Tuesday, 1 June 2021 at 16:25:02 UTC+3, Bonita Montero wrote:
> | request.
> Is this qualified arguing ?
> Öö Tiib's postings are mostly nonsense.
 
I agree ... I was suggesting to not write garbage or to extend compiler
so that the useless garbage is detected and optimized out. For
someone sensible these would be constructive suggestions worth
pursuing. As these were suggested to Bonita Montero who can't
possibly do neither of those it was total nonsense.
Bonita Montero <Bonita.Montero@gmail.com>: Jun 01 06:42PM +0200

> someone sensible these would be constructive suggestions worth
> pursuing. As these were suggested to Bonita Montero who can't
> possibly do neither of those it was total nonsense.
 
I didn't tell garbage. I just wanted to give the compiler the oppor-
tunity to do the optimization which David said that it wouldn't be
done because there the function wouldn't get compiled.
And I did it right by hiding the lambda behind a volatile-Pointer
so that the lambda couldn't be inline-optimized. I could have done
it also a bit simpler:
 
#include <iostream>
 
using namespace std;
 
int main()
{
int volatile i = 123, j = 456, k = 789;
auto f = [&]() -> int
{
return i + j + k;
};
decltype(f) *volatile pFf = &f;
cout << sizeof *pFf << " " << (*pFf)() << endl;
}
 
And the result is the same.
Why is this garbage ?
Bonita Montero <Bonita.Montero@gmail.com>: Jun 01 07:06AM +0200

If you call ...
C:\Program Files (x86)\Microsoft Visual
Studio\2019\Community\VC\Auxiliary\Build\vcvars64.bat
... and then ...
clang --version
... then you get the nearly most recent clang (V11) with MSVC ?
But unfortunately for most benchmarks I wrote MSVC generates
better code than clang.
Juha Nieminen <nospam@thanks.invalid>: Jun 01 07:11AM

> ... then you get the nearly most recent clang (V11) with MSVC ?
> But unfortunately for most benchmarks I wrote MSVC generates
> better code than clang.
 
What optimization flags did you use?
Bonita Montero <Bonita.Montero@gmail.com>: Jun 01 11:06AM +0200

>> But unfortunately for most benchmarks I wrote MSVC generates
>> better code than clang.
 
> What optimization flags did you use?
 
-O3
There are also benchmarks which run faster with clang,
but most run faster with cl.
David Brown <david.brown@hesbynett.no>: Jun 01 11:54AM +0200

On 01/06/2021 11:06, Bonita Montero wrote:
 
> -O3
> There are also benchmarks which run faster with clang,
> but most run faster with cl.
 
-O3 is sometimes faster than -O2, and often slower. Don't use -O3
unless you know what you are doing, and have tested it to see that it is
helpful for your particular requirements. (The same applies to gcc, to
a slightly lesser extent.)
 
clang also has a tendency to be enthusiastic about vectorisation and
loop unrolling that can help for big data sets, but be noticeably bigger
and slower on small sets. You see that especially on -O3, but also on
-O2. Optimising is not just a matter of "bigger number means faster for
all tests".
 
(That said, MSVC can be quite efficient for some kinds of code - it's
entirely possible that it is simply better for the examples you were using.)
Bonita Montero <Bonita.Montero@gmail.com>: Jun 01 12:25PM +0200

> -O3 is sometimes faster than -O2, and often slower. ...
 
For my benchmars it's always faster than -O2. F.e I've got an
improved version of CRC64 and FNV64, which profits a lot from
loop-unrolling.
Lynn McGuire <lynnmcguire5@gmail.com>: May 26 05:06PM -0500

On 5/26/2021 3:44 PM, Scott Lurndal wrote:
>> (>10,000 members) just because it is much faster than std::vector.
 
> Isn't that computer science 101? O(N) vs. [O(1) .. O(Log N)] for
> vector vs std::map (red-black tree).
 
Sorry, never took CS 101 at TAMU. My degree is in Mechanical
Engineering. I did take CS 204 or 304, IBM 370 Assembly Language
Programming, for grins.
 
Lynn
Bonita Montero <Bonita.Montero@gmail.com>: May 26 06:02PM +0200

> I'll have to add this to my list of why the C++ threading library is crap.
 
Because of that ting ascpect ? Have you ever noticed the RAII-flexi-
bility of C++-locking ? Have syou ever noted how convenient it is
to pass arbitrary parameter-lists to your thread as it it would be
a directly called function; compare the work of defining a structure,
to define it, allocate it, fill it, pass it to the thread and deallo-
cate it at the end of the thread - that's all for free in C++ and
the performance is the same !
 
> I would suggest if your code doesn't need to be portable to
> either use posix threads on *nix or its Windows equivalent.
 
That's a lot of work more than with C++-threads.
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: