This will chop off a trailing dot and any white space that follows but not a trailing dot without trailing whitespace. Is that really the intent? Also, it will turn `domain.com.. ` into `domain.com.`
Tangentially related, but I find it somewhat baffling that at some point people thought that using data types with unknown ranges is viable way of producing robust portable programs. It took until C99 to get basic int32_t etc, before that you were mostly relying on bunch of ifdefs to get portable results. The whole mindset for things like short/int/long must have been just so very different than what I'm used to.
It doesn't make sense in the context of today's relatively uniform hardware, but I think the goal wasn't so much portably correct code, but portably efficient code that avoided the need to use assembly language for everything.
The first version of UNIX was written in assembly language for an 18-bit machine. C was invented as part of rewriting UNIX to work on a 16-bit machine and who knows what to expect after that. Machine architectures were a lot less uniform back in the day, and most of those minicomputers are easily beat by some of today's 20 cent microcontrollers.
Given that context, being able to loosely define relative data type sizes based on how efficiently they might be represented on the machine might make more sense.
But you're right, that's quite alien to where we are today.
By the 1980s, Ada was already making the right call of allowing the developer to specify the behavior and exact range of modular integer types for correctness and letting the compiler optimize things for efficiency or performance as needed. It'd be nice to see that approach become more popular.
I’ll admit I couldn’t really follow the blog post. I’ve always thought it’d be fun to do some research and understand a post like this, then blog about what I had to learn to understand the post.
Sounds like a great idea, not "bad form" at all. I think it would be a great help to others in the position you're in, as well as worth doing just for your own self edification, without publishing it.
No, the problem is using the wrong data type: "long". On 32-bit systems, Linux defines long to be 32-bits,vs 64 bits on 64-bit. As another example of how this could be broken: use this code on Windows, either 32 or 64 bit and the code is completely broken because longs are 32-bits regardless of whether the OS is 32 or 64 bit capable. Use time_t as that's the correct type and will do the right thing assuming your C standard lib is up to date.
Well, the problem is that it is casting (t + DAY/2) to a long before it divides by DAY, not after. The whole expression ((t + DAY/2) / DAY) will not overflow 32 bits in any reasonable timeframe, but (t + DAY / 2) will.
This is why people shouldn't write their own time functions (in the same vein as not writing their own encryption code). If it's not used in a public library by many, many other things, issues like these might not be discovered until it's too late, or until Rachel discovers them (but Rachel can't be expected to check all the things).
By extension of that logic, engineers basically shouldn't write anything except very high level application glue code, and only that as a last resort. Rely on libraries made by people who are domain experts or at least have a lot of eyeballs and users, because _every_ problem domain has a lot of ugly warts and major issues. People warn about time and encryption specifically because these issues can be subtle and take years to be exposed, but the same is true for lots of others as well. Don't write your own parsers, network libraries, locking primitives, data structures, filesystems, databases, etc. Except of course, sometimes you have to.
The insight is to not write critical, bug prone code if you don't have to. Encryption, time, primitives, etc., are things that many people need and use and already exist.
If the solution you need doesn't already exist, of course you need to write your own.