Live data from Hacker News

Some dark corners of C

docs.google.com

81–90 of 175 posts

Re: Some dark corners of C

#81
post #37

Most of these "dark corners" have been in C for at least 25 years and have been repeated over an over for at least 20. My main take-away from this is that Google Drive seems like a nice way to put presentations online :-)

> My main take-away from this is that Google Drive seems like a nice way to put presentations online :-)

Don't. I've been trying to access the presentation for 10 minutes and it won't allow me:

    Wow, this file is really popular! Some tools might be unavailable until the crowd clears.
and then I get redirected to https://support.google.com/accounts/bin/answer.py?hl=en&... (which is stupid, because there's nothing cached/cookied for google. In fact, I'm in Firefox's "Private Browsing")

Re: Some dark corners of C

#82

Earlier quoted context omitted.

whoah - I find that construction astonishing. My gcc compiles it with only this warning: foo.c:2:6: warning: ‘main’ is usually a function [-Wmain] hah!

main is probably the only symbol this works with, data is generally put into non-executable sections/pages.

Others will probably be possible, albeit compiler-specific. The IBM xlc compiler / linker chooses to implement C static initializers by simply prefixing them with __sinit_, which tells the linker to automatically glue a call to it into init before calling main. I haven't tried this specific trick in combination with that, but if I had to make a bet it would work exactly the same way.

Re: Some dark corners of C

#83
post #48
post #40

Earlier quoted context omitted.

Hah, a nice article. :-) My favourite sentence from the PHP documentation: string create_function ( string $args , string $code ) "Creates an anonymous function from the parameters passed, and returns a unique name for it ." So there you are. Of course you can choose to be an anonymous value, but you'll get a name assigned by the state, for free. :-) Fascinating logic, captain.

In this case it isn't so weird, since PHP pre 5.3 didn't have first class functions. To pass a function around, you would use a variable containing a string of it's name. create_function was a way to A) not having to define a function separately B) not getting problems with the function being re-defined, since each call would create a new function C) fake closures by generating code. All this should be moot points by…

That's true (except for C), because I can't see how a create_function-defined function closes over its environment), but what I had in mind was the way in which the author of the documentation, obviously one of the PHP core developers, talks casually about "returning the name of an anonymous function". It shows just how much twisted the logic of these people is.

But I suppose that goes naturally hand in hand with the cargo cult approach to language design.

Re: Some dark corners of C

#86
post #79

For "dark corners of C", when I was writing C code I had several serious concerns. Below I list eight such in roughly descending order on 'seriousness': First, what are malloc() and free() doing? That is, what are the details, all the details and exactly how they work? It was easy enough to read K&R, see how malloc() and free() were supposed to be used, and to use them, but even if they worked perfectly I was unsure…

> Fourth, that the strings were terminated by the character null usually sent me into outrage and orbit around Pluto.

Everything is about tradeoffs. Fortran uses space-padded strings with no null terminator. On the positive side, this forces everyone to explicitly pass the length they mean instead of relying on more work at runtime to figure out when to stop by looking for the null sentinel. Passing explicit lengths is good practice in C anyway because you usually avoid having to scan the contents multiple times / multiple calls to strlen at different levels in the stack. While everything should be better in the Fortran case, the class of bugs that persist are even more hard-to-find bugs because poorly written code mis-calculates the length, ignores it, etc., stomping over adjacent memory. This probably won't crash, and since other code has to use an explicit length when accessing the buffer, you usually won't notice the problem at the source of the issue. Contrast that with C, where you're more likely to see an issue immediately as soon as the string is used or passed to something else.

tl;dr Poor programming is poor programming in any language.

Re: Some dark corners of C

#88
post #79

For "dark corners of C", when I was writing C code I had several serious concerns. Below I list eight such in roughly descending order on 'seriousness': First, what are malloc() and free() doing? That is, what are the details, all the details and exactly how they work? It was easy enough to read K&R, see how malloc() and free() were supposed to be used, and to use them, but even if they worked perfectly I was unsure…

> Fourth, that the strings were terminated by the character null usually sent me into outrage and orbit around Pluto. Everything is about tradeoffs. Fortran uses space-padded strings with no null terminator. On the positive side, this forces everyone to explicitly pass the length they mean instead of relying on more work at runtime to figure out when to stop by looking for the null sentinel. Passing explicit lengths…

Yup.

With PL/I the maximum length of the string is set when the string is allocated, usually dynamically during execution. The length can be given as a constant in the source code or set from computations during execution. There is also a current length In Visual Basic .NET, the maximum length of any string is the same, as I recall, 2 GB. Then having the strings be 'immutable' was a cute approach, slightly frustrating at times but otherwise quite nice and a good way to avoid the problems you mentioned.

But, of course, the way I actually used strings in C was close to the way they were supported in Fortran.

And, of course, likely 100,000+ C programmers wrote their own collection of string handling routines where use a struct to keep all the important data on the string, say, allocated or not, pointer to the allocated storage, maximum allocated length, current length, etc. (multi-byte character set anyone?) and then pass just a pointer to the struct instead of a pointer to the storage of the string; in this way, again should reduce the frequency of some of the errors you mentioned.

Re: Some dark corners of C

#89
post #73

On some slides there is shown how particular function is expressed in assembly. I know nothing about that language (I'm talking about assembly; I know c and even like it) and when I tried to find anything how to learn this I faced some problems. I don't know, where should I start, how should I start etc. Can someone point me to good resources or starting points (I prefer linux than windows if that's matters)? (Sorry…

The assembly used were relatively simple and for x86-64 Linux (You can tell it's not for Windows by how function arguments were passed).

You can actually get a firm grasp of the basics just by reading chapter 3 from Computer Systems: A Programmer's Perspective (http://csapp.cs.cmu.edu/public/samples.html) and practice writing some simple command line programs.

Re: Some dark corners of C

#90
post #43

Earlier quoted context omitted.

The purpose of int foo(int x[static 10]) is not to produce a warning - that's just a nice possible side-effect (and only in some cases). The real purpose is to allow the compiler to optimise the compilation of the foo() function itself, under the assumption that x will always point to the first element of an array of at least 10 elements.

What possible optimization would a compiler be able to do, given that arrays are only ever implicit in compiled C?

If it knows the address is valid, it can use a speculative load. If it knows there are enough entries, it can use a wide load. Without that knowledge, such instructions could trigger SEGV due to an invalid pointer or the wide load spilling over a page boundary.
Post reply on HN