Live data from Hacker News

An intro to Zig's integer casting for C programmers

lagerdata.com

21–30 of 135 posts

Re: An intro to Zig's integer casting for C programmers

#21
post #2

> If runtime safety is turned off, you get undefined behavior You already know someone will teach their students to always have it off because its "slower" or something. Make something idiot-proof and the world invents a better idiot. Another language that does safety like this incredibly well is Ada (Ada/SPARK), and I'm unsure why people aren't more hyped about it. So many people hype Rust or Zig or whatever new lan…

Ada / spark may be a great thing. But how do people know?

Is there a good compiler that one can install for free?

Are there a few good and comprehensive books / references / guides, available online for free?

If you want something to become popular, give it away. Ideally, push it. At the very least, have a limited free version. Or turn a bling eye to small-time piracy, as many vendors did for a long time. Or make it dead easy to buy it for $10.

(None of the above works for you? Sorry, you have just turned down 99% of kids who might like to tinker with your tech, love it, and then promote it wherever they go. Your tech may be hot and desired in the narrow circle of pros, but it's not going to become popular and win the world.)

Re: An intro to Zig's integer casting for C programmers

#22
post #15
post #11

Earlier quoted context omitted.

> Everyone knows that only newbies do coding errors in C, so why spend the extra money? /s The Ariane 5 maiden flight disaster illustrated quite clearly that the choice of language has little influence on the actual correctness of a program. Ada on its own is no better than Pascal in that regard. A formally verified and thoroughly tested MISRA C program can be safer and more correct than a sloppily written Ada progra…

Ariane 5 error was caused by the remaining 30% programming errors when we leave out the 70% of software failures caused by C typical errors. So yes, it is quite worthy to reduce the amount of money spent in verification, testing, tooling and culture. The alternative is to just give up that programmers will never learn and just force verification at hardware level, like Google is doing on Android. "Memory Tagging for…

Ironically enough, I recall reading that if the overflow hadn't triggered a hardware exception and instead was silently ignored, the first stage would have survived; the code in question had just been carried over from Ariane 4 and was no longer important for the operation of the booster..

Re: An intro to Zig's integer casting for C programmers

#23
post #7
post #2

> If runtime safety is turned off, you get undefined behavior You already know someone will teach their students to always have it off because its "slower" or something. Make something idiot-proof and the world invents a better idiot. Another language that does safety like this incredibly well is Ada (Ada/SPARK), and I'm unsure why people aren't more hyped about it. So many people hype Rust or Zig or whatever new lan…

Or Modula-2, NEWP, BASIC, or really most languages that aren't copy paste compatibel with C. Ada suffered from its domain, original price of compilers, and the few UNIX vendors that cared to offer compiler like Sun, it was an additional acquisiation on top of UNIX SDK. Everyone knows that only newbies do coding errors in C, so why spend the extra money? /s

Is anyone actively using Modula-2? Actively as in starting new projects, compiler improvements, tooling, community etc.

Re: An intro to Zig's integer casting for C programmers

#24

IME the strict conversion rules in Rust and Zig can be quite a bummer for somebody coming from C because they may add a surprising amount of friction in day-to-day coding. Yes, C code is often way too sloppy when it comes to picking the right type (signed vs unsigned vs float), and it conveniently hides the problems if the wrong choice was made. But sometimes the same value needs to be used in integer and floating-po…

Could you give some examples where the same value needs to be used in integer and floating-point math?

I'm not quite sure if I understood you correctly, but in case you propose that integer float conversion should happen implicitly I have to disagree. While implicitly converting from integer to float/double would probably be fine, implicitly converting from float/double to integer sounds like a recipe for headaches: There are just too many options (truncation/ceil/floor/rounding). Even if you decided that some option should be the standard since it makes sense in 90% of all cases (let's say rounding), you now have a difficult-to-find (since it's implicit) footgun ready to cause damage in the remaining 10% of all cases.

Even in that paragraph lies a small surprise waiting to be found (at least for some people): The floating point standard IEEE 754 defines five different rounding modes - two "normal" modes (Round to nearest, ties to even as well as Round to nearest, ties away from zero) and the additional directed ones mentioned above (truncation, ceil, floor). Interestingly, the default rounding mode (Round to nearest, ties to even) is not the one you probably learnt in school (that would be Round to nearest, ties away from zero). In school, you always round up if you end up exactly between two numbers, i.e. round(0.5) = 1, round(1.5) = 2. However, this introduces a small bias that can manifest itself into a real problem, for example if you round many measurements and then calculate the mean. That's why the default floating-point rounding mode will essentially alternate between rounding up and down, i.e. round(0.5) = 0 and round(1.5) = 2.

Most of the time this is not an issue and you really want the default rounding mode, but I hope this example illustrates why hiding the "implementation detail" of converting floating-point numbers to integers might not be a good idea.

By the way, I just looked up the man page for round(), and to my surprise found that it will always round ties away from zero, independently of the floating-point environment. If you want to round using different rounding modes in C, you apparently have to use nearbyint() and friends after setting up the rounding mode using fesetround().

PS: Of course the rounding modes are all about rounding floating-point values, not necessarily converting them to integers, but I think the point should be clear.

Re: An intro to Zig's integer casting for C programmers

#25
post #15
post #11

Earlier quoted context omitted.

> Everyone knows that only newbies do coding errors in C, so why spend the extra money? /s The Ariane 5 maiden flight disaster illustrated quite clearly that the choice of language has little influence on the actual correctness of a program. Ada on its own is no better than Pascal in that regard. A formally verified and thoroughly tested MISRA C program can be safer and more correct than a sloppily written Ada progra…

Ariane 5 error was caused by the remaining 30% programming errors when we leave out the 70% of software failures caused by C typical errors. So yes, it is quite worthy to reduce the amount of money spent in verification, testing, tooling and culture. The alternative is to just give up that programmers will never learn and just force verification at hardware level, like Google is doing on Android. "Memory Tagging for…

That’s not an alternative to memory safety. That’s just a basic security measure even if you write everything in a safe language like Rust or Zig (let alone the fact that you have enormous C/C++ legacy codebases that are likely still seeing ongoing development due to switching costs). The reason is you will always have some amount of unsafe code when dealing with the hardware and this is a hardening measure to protect against slipups.

Re: An intro to Zig's integer casting for C programmers

#26
post #21
post #2

> If runtime safety is turned off, you get undefined behavior You already know someone will teach their students to always have it off because its "slower" or something. Make something idiot-proof and the world invents a better idiot. Another language that does safety like this incredibly well is Ada (Ada/SPARK), and I'm unsure why people aren't more hyped about it. So many people hype Rust or Zig or whatever new lan…

Ada / spark may be a great thing. But how do people know? Is there a good compiler that one can install for free? Are there a few good and comprehensive books / references / guides, available online for free? If you want something to become popular, give it away . Ideally, push it. At the very least, have a limited free version. Or turn a bling eye to small-time piracy, as many vendors did for a long time. Or make it…

There's an Ada compiler as part of gcc.

The most prominent project that i know of written in ada is ghdl.

Re: An intro to Zig's integer casting for C programmers

#27
post #17

Earlier quoted context omitted.

I think I'd like to get into Ada more, but I'm always a bit unsure on how to select the right toolchain (is the Dragonegg/LLVM option viable today?) etc. I would love to see something like "Rustlings" for Ada, as I found that was a good way to practice not only writing code, but reading it as well. I was able to self-teach Haskell and Erlang without any major problems, and even managed to ship applications written in…

Plenty of learning paths at https://learn.adacore.com/

Thanks, I'll check it out!

(Looks like I found a use for the new Rosetta on my M1 Mac.... I wonder when there will be builds for aarch64 for Darwin)

Re: An intro to Zig's integer casting for C programmers

#28
post #5

IME the strict conversion rules in Rust and Zig can be quite a bummer for somebody coming from C because they may add a surprising amount of friction in day-to-day coding. Yes, C code is often way too sloppy when it comes to picking the right type (signed vs unsigned vs float), and it conveniently hides the problems if the wrong choice was made. But sometimes the same value needs to be used in integer and floating-po…

D doesn't try to "fix" C integer promotion/casts. It's because they aren't bad defaults. As a bonus you can port code from C with less risk. Soon you'll be able to compile it directly. I contributed to found the only discrepancy in D vs C code wrt integer (-byte would yield byte instead of int), and it was fixed so that they match exactly C _conventions_.

C integer promotions are what remains of old computers systems which couldn't handle anything but a 'word'.

It result in things highly inconsistent on modern 64-bit machines:

For example, char/short are automatically promoted to int or unsigned int when an operation is performed on them, but this doesn't happen between int and long.

Simple things like adding two int16_t together to get a int16_t in return is really hard: you need a mask and a extra explicit cast, and you rely on the compiler being smart enough to understand what you are doing and to emit just the instruction you want.

But you don't need to do the same with int32_t, because reasons.

This is a bad default behavior, as it doesn't match either the intuition or underlying hardware, it is inconsistent across all integer types, and to understand why it works that way you need to understand how computers works 30 years ago.

D supporting C integer promotion might be a good thing for portability, but that's it.

Re: An intro to Zig's integer casting for C programmers

#29
post #9

IME the strict conversion rules in Rust and Zig can be quite a bummer for somebody coming from C because they may add a surprising amount of friction in day-to-day coding. Yes, C code is often way too sloppy when it comes to picking the right type (signed vs unsigned vs float), and it conveniently hides the problems if the wrong choice was made. But sometimes the same value needs to be used in integer and floating-po…

C programmers are well known to refer to such programming safety as straighjacket since the Pascal days anyway. There was more than enough time to learn why it was the right option to start with.

Rust does go overboard though, e.g. indexing requires `usize`. You either use `usize` for all your integers, or you end up with a cast-salad.

   arr[i as usize]
This is actually risky, because even when you only meant to extend, you can also accidentally truncate or change sign. `as` does all of these things without a warning, and mixed with type inference it can easily lead to surprises.

Rust makes it worse by insisting on a theoretical support for 16-bit and 128-bit `usize` regardless of the target platform, so you can't use `a[i.into()]` to infallibly convert `u32` to `usize` on 32-bit and 64-bit platforms.

The correct syntax is:

   arr[usize::try_from(i).unwrap()]
which is painfully verbose. In larger expressions it's almost an obfuscation of what the code is actually doing.
Post reply on HN