Live data from Hacker News

C Is Not Reasonable

osr.com

21–30 of 71 posts

Re: C Is Not Reasonable

#21
post #2

First line: > ULONGLONG tableOffset; It's starting well, for a C example... Oh, and it ends even better: > I write drivers for a living, not scientific or statistical analysis software. During this project, I quickly learn that casting everything to (double) was my friend. When in doubt, stick a (double) in front of it and test it again. In the end, the code worked pretty well. The customer was happy. We got paid. o_…

> OKOK, so you write drivers but don't know about C types, standard types, fixed-length types That was my thought as well. I've occasionally been hired to write windows kernel drivers and I'd say that if you don't have a good grasp of stuff like C's type promotion, you're gonna have a bad time. Surprised to see this from OSR, which was a great source of info for driver development arcana when I was doing it. Edit: re…

You're both missing the point.

Knowing the rules is not the same thing as consistently applying the rules across code you wrote or didn't write (or wrote late at night). The first is easy for a human, the second is hard for a human. That's why language researchers post-1972 have had jobs.

Re: C Is Not Reasonable

#22
post #6
post #4

Earlier quoted context omitted.

As someone who only has a passing knowledge of C, why is that wrong? Is it because it should be "uint_64" instead?

Because ULONGLONG is reminiscent of Windows, Visual Studio, and its flaky and outdated support for C. It does not remove the argument of C choosing to use the type of the operands to determine the width of the calculus, but it shown that this is not portable, standard C. Also, if the guy writes drivers, you should expect him to be aware of these problems, possibly having built an extensive set of preprocessor macros…

The ULONGLONG typedef is a 64 bit integer. They should use that.

By the way, MS's compiler has had stdint.h since 2010. So they are making improvements, slowly.

Re: C Is Not Reasonable

#23

It is strange to pick on C for this, as I cannot think of a single language that works the way the author seems to want. The only exception I can think of is Perl, which has the "wantarray" function that lets a function vary its behavior based on what its return is being assigned to: http://perldoc.perl.org/functions/wantarray.html With that exception, it's pretty much always assumed that an expression is evaluated i…

> It is strange to pick on C for this, as I cannot think of a single language that works the way the author seems to want.

Agreed, though recent crop of languages with less implicit conversion will reject the entire thing rather than silently expand the value at the end, e.g. in Rust

    error[E0308]: mismatched types
     --> :7:19
      |
    7 |     tableOffset = (l1Index * L1_TABLE_GRANULARITY) +
      |                   ^ expected u64, found u32
    
    error: aborting due to previous error

Re: C Is Not Reasonable

#24
post #6

Earlier quoted context omitted.

Because ULONGLONG is reminiscent of Windows, Visual Studio, and its flaky and outdated support for C. It does not remove the argument of C choosing to use the type of the operands to determine the width of the calculus, but it shown that this is not portable, standard C. Also, if the guy writes drivers, you should expect him to be aware of these problems, possibly having built an extensive set of preprocessor macros…

To be fair, though, this entire comment thread echoes the main point of the article: in what world is it reasonable to have to keep track of such things?

Drivers, for one. Any world where performance is so critical that you want to ensure you're fitting as much information as you reasonably can into the L1 and L2 caches for the computations you must do.

There's even still a role in this world for people to fine tune the assembly code for a specific execution environment to make their HPC models execute faster.

Re: C Is Not Reasonable

#25
post #7

Arithmetic is surprisingly hard to get "right". You might try to generalise from this example that "multiplying two N bit numbers together should give a result 2N" wide, then discover that for simple examples you run out of machine bits. Then there's overflow/saturation handling, which is a mess everywhere: lots of systems have hardware support for saturation arithmetic, but you can't conveniently specify it in C. If…

For modern applications programming, arbitrary-precision is probably the right way to do integer arithmetic. Python does that, and it doesn't seem to cause any trouble. The people who need to do massive amounts of numeric stuff know who they are and can take the time to learn the relevant arcana, but your typical cat pictures app never has to worry about how big any of its integers are.

Re: C Is Not Reasonable

#26
post #18

It is strange to pick on C for this, as I cannot think of a single language that works the way the author seems to want. The only exception I can think of is Perl, which has the "wantarray" function that lets a function vary its behavior based on what its return is being assigned to: http://perldoc.perl.org/functions/wantarray.html With that exception, it's pretty much always assumed that an expression is evaluated i…

It would be nice if languages allowed us to overload function names with the exact same parameters but different return types. The compiler or runtime environment should be able to select the correct implementation automatically based on type inference, or allow the programmer to specify which one should be used with an annotation. This would make some code a little cleaner instead of having to give all of those func…

> It would be nice if languages allowed us to overload function names with the exact same parameters but different return types.

Haskell's typeclasses kind-of do that. `read` has type `Read a => String -> a`, so the result's type `a` (which can be inferred) drives which "Read" instance will be used:

    Prelude> read "1" :: Int
    1
    Prelude> read "1" :: Float
    1.0

Re: C Is Not Reasonable

#27
post #4
post #2

First line: > ULONGLONG tableOffset; It's starting well, for a C example... Oh, and it ends even better: > I write drivers for a living, not scientific or statistical analysis software. During this project, I quickly learn that casting everything to (double) was my friend. When in doubt, stick a (double) in front of it and test it again. In the end, the code worked pretty well. The customer was happy. We got paid. o_…

As someone who only has a passing knowledge of C, why is that wrong? Is it because it should be "uint_64" instead?

It's silly because no casts give you an integer type that is too small, but casting to double converts to floating point, performs floating point math, then assigns the result to the correct type they should have used in the beginning.

Floating point math in low level C code is very often a WTF. You most often want integers.

Re: C Is Not Reasonable

#28
post #18

It is strange to pick on C for this, as I cannot think of a single language that works the way the author seems to want. The only exception I can think of is Perl, which has the "wantarray" function that lets a function vary its behavior based on what its return is being assigned to: http://perldoc.perl.org/functions/wantarray.html With that exception, it's pretty much always assumed that an expression is evaluated i…

It would be nice if languages allowed us to overload function names with the exact same parameters but different return types. The compiler or runtime environment should be able to select the correct implementation automatically based on type inference, or allow the programmer to specify which one should be used with an annotation. This would make some code a little cleaner instead of having to give all of those func…

> or allow the programmer to specify which one should be used with an annotation.

That's exactly:

> give all of those functions different names.

Re: C Is Not Reasonable

#29
C is a minimal abstraction over asm and I wouldn't be surprised if this behavior can be configured in some C compiler, even though it would be odd to do so.

What I find surprising is when people say C is a simple and small language that's nice to build portable programs in. So much of C is undefined behavior or implementation specific that many professional users pin a certain compiler toolchain version for a project. Part of it is due to changing and hard to predict optimizer passes, but most of it is due to the purported portability feature of C. I mean, if I leave a lot of the semantics undefined or to be defined per compiler+target, then it's not really a portability abstraction. Not to mention the missing or, if you consider POSIX, inconsistent across platforms, C stdlib.

It's educational to look into Modula-3 and SPIN. SPIN is like MirageOS but with dynamic loading of components whereas in Mirage everything is compiled ahead of time into the final image. I mention Modula-3 because it's of similar age as ANSI-C and serves as an example of an OS written in a comparatively safe language around the same time Unix won and gave us the hegemony of C (with all the avoidable security fallout ever since).

Even though software isn't like the real world and could be improved substantially unlike world politics, we still continue dealing with bugs due to C, although we have better options. I think as long as new operating systems or libraries and applications are written in C, this won't change. Just the idea of writing kernels for IoT systems in C in 2016 makes no sense from a reliability and high assurance perspective. Getting there half way would be exposing hard-to-misuse C APIs where the implementation is in a safe language (Rust, ATS2, etc). For the moment consuming C APIs is the cross platform library interface we have to deal with, but having at least the implementation be safe would go a long way.

Re: C Is Not Reasonable

#30
post #7

Arithmetic is surprisingly hard to get "right". You might try to generalise from this example that "multiplying two N bit numbers together should give a result 2N" wide, then discover that for simple examples you run out of machine bits. Then there's overflow/saturation handling, which is a mess everywhere: lots of systems have hardware support for saturation arithmetic, but you can't conveniently specify it in C. If…

Yeah, I recently read on some forum someone who was looking for a quick C++ training for a friend and said "he doesn't need a deep training, just some basic syntax, he's not a programmer, that doesn't interest him, he's just doing scientific calculus".

I was like: Oh boy... getting arithmetic calculation right is really tricky and you have to understand many not-obvious details, especially concerning the behaviour of floating-points numbers, and then you have to make choices or compromises depending on your requirements. But if you have no idea of the limitations of CPUs and languages, the naïve requirement is just "exact, full-precision, as long as needed" and you'll hit some bugs sooner or later.

Post reply on HN