[HN Gopher] Truthiness in C
___________________________________________________________________
Truthiness in C
Author : todsacerdoti
Score : 65 points
Date : 2023-09-15 13:04 UTC (9 hours ago)
(HTM) web link (dxuuu.xyz)
(TXT) w3m dump (dxuuu.xyz)
| thesnide wrote:
| Navigating down the hyperlinks rabbit hole, I discovered native
| BCD asm instructions im x86
|
| https://www.felixcloutier.com/x86/aam
|
| Who said that curiousity was bad?
| recursive wrote:
| No one said that.
| zengid wrote:
| It killed the cat.
| D-Coder wrote:
| What did the cat want to know?
| irq wrote:
| That cat had one hell of a life before it died though.
| giomasce wrote:
| If it had to deal with BCD it was a hell indeed...
| jonny_eh wrote:
| Try int -> bool -> int
| stefanos82 wrote:
| If I'm not mistaken, the `(bool)` is unnecessary due to how
| implicit conversion works: `In a return statement, the value of
| the operand of return is converted to an object having the return
| type of the function` [1] ...unless I understood it incorrectly
| :/
|
| [1] https://en.cppreference.com/w/c/language/conversion
| swinglock wrote:
| That's correct.
| projektfu wrote:
| so return (bool)x;
|
| is equivalent to return 0!=x;
|
| and return !!x;
|
| https://godbolt.org/z/Gq5j8j66a
|
| Sorry, this is the C link:
|
| https://godbolt.org/z/crxecb9c3
| colesbury wrote:
| This misses the fact that signed integer promotions are generally
| _not_ free because they require sign extension. For example, the
| cast in b() emits a `movsx` (move with sign-extension). `movsx`
| is not free in the ways that `mov` can be.
|
| `mov` can be "free" in two ways:
|
| - the compiler can frequently avoid emitting the `mov` when part
| of a larger operation
|
| - modern CPUs handle `mov` instructions earlier in the pipeline
|
| Neither of those are true for `movsx`.
| marcosdumay wrote:
| Yeah, C now has bool natively...
|
| I'm quite confident the compiler will optimize that test-and-move
| away as soon as you use the bool for something, giving you the
| same assembly as a last century's `typedef bool int`.
| _kst_ wrote:
| C has had _Bool natively since the 1999 ISO standard (24 years
| ago). The standard header <stdbool.h> has "#define bool _Bool".
| (The ugly name "_Bool" was chosen to avoid conflicting with
| existing code.)
|
| The upcoming C23 standard will define "bool" as a keyword.
| kevin_thibedeau wrote:
| More significantly, true and false are now keywords.
| danobi wrote:
| I think it has to keep it for externally visible functions,
| right?
| marcosdumay wrote:
| Yes, you are right. If you have to put a bool on the stack,
| it will have to keep the instructions.
| strkitten wrote:
| Did you mean `typedef int bool`?
| _kst_ wrote:
| No, _Bool is a distinct type, introduced by the 1999 edition
| of the standard.
| Longhanks wrote:
| No, marcosdumay wrote 'typedef bool int', by which he/she
| probably meant 'typedef int bool', which was not so
| uncommon when there was no native bool type in C, since the
| former would be illegal since the standard forbids
| typedefing already existent types such as int. strkitten
| informed about the probable typo.
| _kst_ wrote:
| Sorry, I managed to miss the context.
| [deleted]
| thxg wrote:
| The article is very recent (September 2023 [1]), mentions that
| "rax is used to return integer values" in the SysV ABI (hence
| implicitly the 64-bit SysV ABI). Also confirmed in this excerpt:
|
| > Note that the top 56 bits in rax are not zeroed - they contain
| junk. This is fine b/c the compiler will only make callers check
| the lowest bit of a register for boolean operations. This is why
| changing the compiler's "understanding" (ie the cast) is
| necessary.
|
| ... and yet, the function ABI is clearly i386 (fetching arguments
| from stack) and indeed everything is compiled with -m32 [2] (i.e.
| 32-bit SysV ABI). This is a strange contradiction in 2023. On the
| Intel/AMD side, x86_64 has been prevalent (and the default)
| for... more than 15 years?
|
| It does not invalidate the article's point. But it is slightly
| confusing....
|
| [1] https://dxuuu.xyz/
|
| [2] https://godbolt.org/z/ff8r44nKn
| AshamedCaptain wrote:
| The article has too many x86 assumptions. The casts are most
| definitely _not_ free, because there are multiple operations
| like sign-extending, zero-extending, etc. which depend on the
| ABI. The fact that these are all almost free in x86 is
| irrelevant since some architectures will have to go out of
| their way to implement the operation (albeit the ABI is usually
| designed to make these operations simple). Similarly, I could
| also imagine another architecture having a shorter instruction
| to set a register to 0/1, or even one where _Bool is defined
| with the machine word size and thus doesn't need any cast
| whatsoever (not even sign extension).
|
| On such architecture "casting to bool" would be free, but
| other, narrowing type conversions would not.
| danobi wrote:
| Above two comments are very helpful, thanks. I've corrected
| the -m32 issue.
|
| And thanks for pointing out the x86/ABI assumptions. Had not
| considered that. It's certainly interesting to think about.
___________________________________________________________________
(page generated 2023-09-15 23:01 UTC)