Live data from Hacker News

No way to parse integers in C (2022)

blog.habets.se

101–110 of 117 posts

Re: No way to parse integers in C (2022)

#101
post #95

Earlier quoted context omitted.

It's a little awkward, because you'd need to parse the strings in reverse, but if all you need to do is sum, you can do it one digit at a time, while at any given moment only handling only one character from each input string, a carry byte, and one output character.

You don't need to parse the strings in reverse. That's for printing integers, not parsing . Roughly: int stdin_atoi() { int i = 0; while (1) { int c = getchar(); if (c >= '0' && c

That method requires storing an arbitrarily large number, whereas for the least-significant-character-first method, the math itself could be done without using any more data than two input bytes, one of which could double as an output byte, and a carry byte.

Re: No way to parse integers in C (2022)

#102
post #99

Earlier quoted context omitted.

I think you're using "crash" to mean "exit early". I am using "crash" in the sense of "this program did something causing the OS to terminate it externally". I suppose that's a real point of difficulty in communication across different programming languages. We agree that the program should exit early. I think we agree it should do it cleanly and intentionally. I'm adding the constraint that "crash" doesn't necessari…

Interesting difference in nomenclature. For me, "crash" absolutely includes intentional early termination. A Rust panic, for example. I think that that's by far the dominant usage of crash. It would surprise me if someone used the word crash but intended to exclude panics, etc.

It's a very language-dependent meaning. In C, the only type of crash is the OS shutting it down on some sort of trap. Everything else is the result of an explicit code path. Since we're talking about C, it's the definition I'm using. In other contexts, other definitions will apply.

Re: No way to parse integers in C (2022)

#103

Earlier quoted context omitted.

In C, errors are usually indicated by a negative return value constant, crashing the program with abort, or setting the errno global (thread-local, but whatever) and expecting callers to check it. Sometimes multiple of those.

One reasonably common pattern is to have the return value indicate success / error, and you pass in a pointer to the value which will be mutated if successful.

Yep, lots of the Windows API does it this way.

Re: No way to parse integers in C (2022)

#104

I wasn't in this class myself, but one prof at my alma mater started his "Programming 201" class with the simplest assignment: write a C program that accepts two integers from the user and prints their sum. It actually was the only assignment for the rest of the semester, since he has a test suite that would humiliate the students gently at first, but would ultimately pipe a billion nines into stdin as the first argu…

That’s golden!

Would make an excellent “interview question from Hell”!

Re: No way to parse integers in C (2022)

#105

Another case many integer parsing functions get wrong is that they interpret a leading 0 as an octal indicator. That should be opt-in via a flag, if it needs to be supported at all. Unix file permissions are the only deliberate use of octal I've ever seen.

It used to be much more common. In the 70s there was a lot of collective hesitance to use hex with its strange letter digits. Octal was the compact representation of choice.

Also, some very old computers had 36-bit words. Word sizes on modern computers are virtually always powers of 2, but it hasn't always been that way.

And octal is more convenient for output via 7-segment LEDs and for input via numeric keypads.

Re: No way to parse integers in C (2022)

#106
How could an api for number parsing ever be designed to return 0 for invalid input, for a function where 0 is also a common (perhaps the most common) return value for a valid input?

This wouldn't even pass a cursory sanity check of the api from a beginner developer, how did it end up in a standard library at all? Was it a mistake and then it was just too late to remove it?

Any function that can either succeed or fail, which is basically every parsing function, must typically indicate success or failure. You can terminate the program or you can return an object that itself indicates failure (such as -1 when finding a positive index) but if ALL values of the return type CAN be valid then the success state must be a separate return value.

What's the purpose of the function atol() if it doesn't have that? Is it "It's still useful for trusted input we know is a string representation of a long" (E.g. for bounded number roundtrip)? That seems awfully limited. But perhaps such a scenario was perhaps more common in 1960?

Re: No way to parse integers in C (2022)

#107
post #86

Earlier quoted context omitted.

Passing a negative value to a function that is specifically for converting strings into unsigned numbers is pretty much an error. In the case of functions that return an unsigned number, at least, negative return values can represent errors. It’s more fun when the result can be signed though. Maybe strcmp with the representation of the LONG_MAX, and if it doesn’t match, call strtol and watch for a LONG_MAX indicating…

If that's an error then so is passing in a non number. So catch 22. You can only check for valid numbers if the number is valid?

That's the C way, yes.

Re: No way to parse integers in C (2022)

#108

Earlier quoted context omitted.

If that's an error then so is passing in a non number. So catch 22. You can only check for valid numbers if the number is valid?

That's the C way, yes.

No. This is more like if strcmp compared null terminates strings, but can only compare strings that are in fact equal.

Re: No way to parse integers in C (2022)

#109
post #78

Earlier quoted context omitted.

The point of this post, though, is even something as simple as "give me this string as an integer" doesn't have an answer that doesn't come with "are you OK with this best effort parse under these edge cases? Oh and we use this number as error, so you can't parse that". Like… edge cases? It's parsing a number ! We're not talking about I/O on hard vs soft intr NFS mounts, here. There's a right answer. strlen(), on val…

Somewhat true, but C is pretty close to translating directly to machine code, even if most compilers now do so many complex things the assembly can be pretty far off. My point being is that if you have a type int in your program, it's specifically tied to the byte size of an integer on the target platform. While it can be 8, 16, 32, 64 bits, it's defined based on what the target platform supports efficiently. So, whe…

> C is pretty close to translating directly to machine code

The C standard defines only its abstract machine, not actual hardware.

> The language means different things on different platforms but it's still defined exactly on the target platform

It's implemented to support a target platform, so that programs behave as if they ran on the abstract machine.

It'd be nice if we could move more stuff from UB to implementation defined.

Do keep in mind that target platform can change, in this regard. E.g. IIRC OpenBSD doesn't guarantee the ABI backward compatibility that Linux does, and can change things like size of int if they want, between versions.

> I also understand why C is like it is

Yup. It can be true that I understand why, and still understand that it's 2026.

Re: No way to parse integers in C (2022)

#110
post #80
post #59

Earlier quoted context omitted.

Is this sarcasm? I thought C didn't fix the size of int because they were trying to make C programs "portable" between architectures with different natural word sizes. It was a mistake, but I remember that as being the stated reason. I'm happy to be corrected if I'm misremembering my history though.

Why would it be a mistake? It's efficient for the target platform. The same code can be compiled for different platforms, yes, but the assembly and machine code will vary significantly, so it could behave differently. Porting to a new platform was usually a very complex process, but the code produced was efficient . Nobody seems to care about this nowadays, though, it seems.

Except the way it's done in C is illogical to the point where it negates the value proposition.

People expect numbers to support specific ranges and it is fine to define the data types numerically rather than as a concrete bit pattern, but C just takes the cake.

Char is at least 8 bits, short is at least 16 bits, int is at least as big as short (genius idea), long is at least 32 bits, long long is at least 64 bits.

The point of "int" is to be the integer equivalent of size_t and therefore be of word size.

But nobody uses int like that. Everyone assumes it's a 32 bit datatype when it isn't.

The use case where you port existing C code to a microcontroller is extremely unappealing, because the number range gets changed under your feet. When I've had to work on embedded software everyone just used int8_t, int16_t, int32_t, int64_t for portability instead.

Post reply on HN