Earlier quoted context omitted.
>The %n functionality also makes printf accidentally Turing-complete No it doesn't. Printf has no way to loop so it's not Turing complete. Even if you did what the IOCCC entry did with putting it into a loop it still wouldn't be Turing complete as it would not have an infinite memory.
Nothing real is "Turing complete" if it requires infinite memory. That's a property only abstract machines can have. In common parlance, something is Turing complete if it can compute arbitrary programs that can be computed with M bits of memory, where M is arbitrary but finite.
Lesser known tricks, quirks and features of C
121–130 of 189 posts
Re: Lesser known tricks, quirks and features of C
#122Earlier quoted context omitted.
Why are these not compiler errors by default? Opting in to such important safety features seems like broken design.
One reason is locale-dependent format strings which are loaded from resource files. Also, in personal projects, I almost always used custom wrapper functions for printf/fprintf/sprintf for various reasons, so that default wouldn’t be of much use, unless maybe I could enable it for the custom functions.
(I have no recommendations. When I've seen this stuff done properly, on the occasions I've managed not to avoid doing it, it's always been using some in-house system.)
Re: Lesser known tricks, quirks and features of C
#123Earlier quoted context omitted.
One reason is locale-dependent format strings which are loaded from resource files. Also, in personal projects, I almost always used custom wrapper functions for printf/fprintf/sprintf for various reasons, so that default wouldn’t be of much use, unless maybe I could enable it for the custom functions.
I've never seen locale-dependent format strings work well. The translators will change the formatting codes, and you can't change the order of the formatted arguments. You are much better off with some other mechanism for this. (I have no recommendations. When I've seen this stuff done properly, on the occasions I've managed not to avoid doing it, it's always been using some in-house system.)
You can with the $ syntax. Never seen it used though. Maybe it isn't very portable.
Re: Lesser known tricks, quirks and features of C
#124Re: Lesser known tricks, quirks and features of C
#125I wish there was a language "between" assembly and C: basically assembly with some quality-of-life improvements. Shortcuts to reduce redundant chores (like those multiple instructions to load one 64-bit number into an ARM register) but minimal "magic" or unintended consequences as in C. Things like maybe a function call syntax like: CALL someFunc(R1: thingForRegister1, @R7: pushR7ThenPopOnReturn, R42: [memoryAddressF…
PRINTF "main_task: sf=%p",ebp
PRINTF " sf: 1=%d 2=%d 3=%d 4=%d",dword [ebp+8],dword [ebp+12],eax,ebx
I'm using NASM and it wasn't hard to write the macro to do so.Re: Lesser known tricks, quirks and features of C
#126> The 0 width field tells that the following bit fields should be set on the next atomic entity (char). This isn't correct since int can't be less than 16-bits. Fields are placed on the nearest natural alignment for the target platform, which might not support unaligned access.
So yeah, the placement in memory might be `xxxxx000 00000000 yyyyyyy0` but it could also be `yyyyyyy0 00000000 xxxxx000` or `yyyyyyy0 00000000 00000000 xxxxx000` or anything else.
Bitfields are very misunderstood and really only safe to treat as an ADT with access through their named API, not their bit placement ABI. People misuse them a lot.
Re: Lesser known tricks, quirks and features of C
#127Earlier quoted context omitted.
"format not a string literal" is one warning I always upgrade to an error. Dear reader: you should do this, too!
I don't like a lot of things in C++, but one thing worth praising in particular is std::format std::format specifically only works for constant† format strings. Not because they can't make it work with a dynamic format, std::vformat is exactly that, but most of the time you don't want and shouldn't use a dynamic format and the choice to refuse dynamic formats in std::format means fewer people are going to end up shoo…
Re: Lesser known tricks, quirks and features of C
#128Earlier quoted context omitted.
I don't believe those are functionally / semantically equivalent - couldn't care less does imply a min() value of care. In contrast, the author is suggesting a comparative only. And, on careful re-reading, I suspect the author is having a play on syntax & semantics here -- the context of the quote is: > You may ask, since when C has such operator and the answer is: since never. --> is not an operator, but two separat…
Hah, unfortunately this bit of "poetry" wasn't intentional. I just meant that C does care about whitespace, just not a lot.
'cares not so much' / 'doesn't care so much' might also work in your context.
Re: Lesser known tricks, quirks and features of C
#129Earlier quoted context omitted.
I think the problem with this is the C compiler has to find a solution which work with all the architectures it is expected to support. It order to achieve this, it must generalize in some areas and have flexibility in others. C programmers are required to be familiar with both the specifics of the architectures they are building for and the idiosyncrasies of their complier. I always assumed most other compiled langu…
> Bitfields in C can be manageable. For the use case of specifying a more efficient representation of a fiction confined to the program, then no harm, no foul. But the use case of specifying a hardware- or network- or ABI-specified data layout, then you need those bits in exactly the right spot, and the compiler should have no freedom whatsoever. (I'm thinking of the case of network protocol packets and hardware memo…
The compiler itself is not taking a liberal approach to bit field management, it is only working within the restriction of the type (I am speaking for GCC here, I can't vouch for others). But if you think of them as an interface to store packed binary data freely without limitations I can understand why they seem frustrating. They are much more intuitive when you consider them as being restricted to the type.
Re: Lesser known tricks, quirks and features of C
#130> volatile type qualifier > This qualifier tells the compiler that a variable may be accessed by other means than the current code (e.g. by code run in another thread or it's MMIO device), thus to not optimize away reads and writes to this resource. It's dangerous to mention cross-thread data access as a use case for volatile. In standard C, modifying any non-atomic value on one thread, while accessing it on another…