Earlier quoted context omitted.
> This is no longer true of C++. As of C++20, signed integer types are defined to use two's complement. [0] I don't think C intends to do the same. As no good language lawyer discussion should be free from pedantry, there is no such thing as "As of C++20". C++20 is just a new version of the C++ standard. Projects that target C++11 or C++14 or C++17 are all still here and won't go away any time soon, and the respectiv…
> C++20 is just a new version of the C++ standard. and per ISO rules, older versions are withdrawn (as can be confirmed for C++ here: https://www.iso.org/standard/79358.html ) and not to be used anymore: https://www.iso.org/files/live/sites/isoorg/files/store/en/P... Other reasons why a committee may decide to propose a standard for withdrawal include the following : ▸ ▸ the standard does not reflect current practice…
Summary of C/C++ integer rules
81–90 of 98 posts
Re: Summary of C/C++ integer rules
#82[Dons language lawyer hat] > floating-point number types will not be discussed at all, because that mostly deals with how to analyze and handle approximation errors that stem from rounding. By contrast, integer math is a foundation of programming and computer science, and all calculations are always exact in theory (ignoring implementations issues like overflow). Integer overflow is no mere implementation issue, any…
What is the reference to "Dons"?
Re: Summary of C/C++ integer rules
#83Earlier quoted context omitted.
> Maybe I'm spoiled by other languages with more powerful type systems, but this is exactly what I want my types to do! Isn't this why we have type traits and concepts and whatnot in C++ now? If not for semantics, why have types at all, the compiler could figure out what amount of bytes it needs to store my data in, after all. yes, but understand that, despite the name, what unsigned models in C / C++ is not "positiv…
+1 for this. I was just bitten by this last week, when I switched from using a custom container where size() was an int to a std::vector where size() is size_t. The code was check-all-pairs, e.g. for (int i = 0; i Which worked just fine for int size, but failed spectacularly for size_t size when size==0. I totally should have caught that one, but I just couldn't see it until someone else pointed it out. And then it w…
Re: Summary of C/C++ integer rules
#84Earlier quoted context omitted.
> C++20 is just a new version of the C++ standard. and per ISO rules, older versions are withdrawn (as can be confirmed for C++ here: https://www.iso.org/standard/79358.html ) and not to be used anymore: https://www.iso.org/files/live/sites/isoorg/files/store/en/P... Other reasons why a committee may decide to propose a standard for withdrawal include the following : ▸ ▸ the standard does not reflect current practice…
Wow. Didn't know this. It doesn't have any bearing whatsoever on reality though. If it did, I wouldn't still be writing C++98 conformant C++.
Re: Summary of C/C++ integer rules
#85Earlier quoted context omitted.
> No need to enforce your semantics through type Maybe I'm spoiled by other languages with more powerful type systems, but this is exactly what I want my types to do! Isn't this why we have type traits and concepts and whatnot in C++ now? If not for semantics, why have types at all, the compiler could figure out what amount of bytes it needs to store my data in, after all. I use types for two things: to map semantics…
Would you really write a function find_prime_factors() that takes an input of type "integer" and an output of type "prime", that you have previously defined? Then if you want to sum or multiply such primes you have to cast them back to integers. Maybe it makes sense for you, but for me this is the textbook example of useless over-engineering. The same ugliness occurs when using unsigned types to store values that hap…
For the same reason, say, in an HTTP server I could store a request as a char* or std::string, but I would definitely create a class that ensures, upon construction, that the request is valid and legitimate. Code that processes the request would accept HTTPRequest, but not char*, so that unverified requests cannot even risk to cross the trust boundary.
Re: Summary of C/C++ integer rules
#86Earlier quoted context omitted.
"Undefined behavior" really means that the standard doesn't define what should happen and that the compiler is therefore free to do whatever it pleases, under the assumption that such code will never occur. Reminds me of the examples where the code gets compiled in a way where a branch that returns from the function is unintuitively always taken because the compiler was able to detect that there is undefined behavior…
> So yeah, undefined behavior isn't "implementation defined" nor "unportable" but rather "illegal not allowed wrong code". There are edge-cases even there. Calling a function generated by a JIT compiler is undefined behaviour, but there's a gentleman's agreement that the compiler won't screw it up for you. Almost all C/C++ compilers promise that floating-point division-by-zero results in NaN (the IEEE 754 behaviour),…
Though you're not writing C/C++ in that case. You're writing "C/C++ for that particular architecture, ABI, OS and compiler".
In general C/C++, if your code is correct every present and future, known and unknown compiler is supposed to generate a correct executable. If they don't, they have a bug. You can pretend to be smarter and go UB, but then the responsibility shifts on you, you have (in principle) to validate each compiler and environment and you can claim no bug on anybody other than you.
Re: Summary of C/C++ integer rules
#87Earlier quoted context omitted.
> So yeah, undefined behavior isn't "implementation defined" nor "unportable" but rather "illegal not allowed wrong code". There are edge-cases even there. Calling a function generated by a JIT compiler is undefined behaviour, but there's a gentleman's agreement that the compiler won't screw it up for you. Almost all C/C++ compilers promise that floating-point division-by-zero results in NaN (the IEEE 754 behaviour),…
> There are edge-cases even there. Calling a function generated by a JIT compiler is undefined behaviour, but there's a gentleman's agreement that the compiler won't screw it up for you. Though you're not writing C/C++ in that case. You're writing "C/C++ for that particular architecture, ABI, OS and compiler". In general C/C++, if your code is correct every present and future, known and unknown compiler is supposed t…
Re: Summary of C/C++ integer rules
#88In the myths section: > char is always 8 bits wide. int is always 32 bits wide > Signed overflow is guaranteed to be wrap around. (e.g. INT_MAX + 1 == INT_MIN.) Are there any current, relevant hardware architectures where this is not true (e.g. bytes are not 8 bits, and integers are not 2's complement)? E.g. what's the point of "portability" if there is no physical hardware around anymore where those restrictions wou…
> Are there any current, relevant hardware architectures where this is not true (e.g. bytes are not 8 bits, and integers are not 2's complement)? For char, not sure, but the problem with signed overflow is not that you can't be sure whether it's 2's complement, it's that the compiler is allowed to assume it won't happen. So, if you read two numbers into 2 ints and add them up, then check for overflow somehow, the com…
In practice compilers sould be considered to follow Murphy's Law: Undefined Behavior will work perfectly fine when on a developer's machine or when observed by any support or QA staff, but will occasionally cause intermittent problems on production machines when observed by users or during demonstrations to executives.
Re: Summary of C/C++ integer rules
#89> Having signed and unsigned variants of every integer type essentially doubles the number of options to choose from. This adds to the mental burden, yet has little payoff because signed types can do almost everything that unsigned ones can. Unsigned types are quite useful when doing bit twiddling because they don't overflow or have a bit taken up by the sign.
> Unsigned types are quite useful when doing bit twiddling because they don't overflow or have a bit taken up by the sign. That's essentially their only application. The rest are stupid single-bit memory-size optimizations. As Jens Gustedt noted, it's one of the (many) misnomers in the C language. It should be better called "modulo" instead of "unsigned". Other such misnomers that I recall: unsigned -> modulo char ->…
const -> read_only_view is better
Re: Summary of C/C++ integer rules
#90Earlier quoted context omitted.
I didn't mean C is not fast or not faster than other languages. It's still the fastest one I believe. What I meant is undefined behaviors allow compilers to optimize in a way that would not be possible otherwise. So, it might be a deliberate decision back then, to leverage performance. I don't know, just an idea.
It used to be "folk knowledge" that only Fortran and hand-crafted ASM were faster. Not sure if that's still (or ever was) true.