TE
TechEcho
Home24h TopNewestBestAskShowJobs
GitHubTwitter
Home

TechEcho

A tech news platform built with Next.js, providing global tech news and discussions.

GitHubTwitter

Home

HomeNewestBestAskShowJobs

Resources

HackerNews APIOriginal HackerNewsNext.js

© 2025 TechEcho. All rights reserved.

Some dark corners of C

352 pointsby fayimoraabout 12 years ago

26 comments

elibenabout 12 years ago
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.<p>My main take-away from this is that Google Drive seems like a nice way to put presentations online :-)
评论 #5348903 未加载
gjulianmabout 12 years ago
<p><pre><code> #define struct union #define else </code></pre> That's evil. I have to do it in someone's code some day just to have some fun.<p>But, apart from that, it's a really nice compilation. I didn't know about the compile time checks of array sizes, but I have a doubt. What if I pass to a method declared<p><pre><code> int foo(int x[static 10]) </code></pre> this pointer<p><pre><code> int* x = (int*) calloc(20, sizeof(int)); </code></pre> Does the compiler skip the check? Does it give me a warning?<p>EDIT: Funnily enough, in Mac it doesn't give any warning, neither for pointers nor for undersized arrays (ie, foo(w[5]) doesn't give a warning). And I've compiled with -std=c99 -pedantic -Wall.
评论 #5348108 未加载
评论 #5348161 未加载
评论 #5348466 未加载
评论 #5348237 未加载
评论 #5348289 未加载
评论 #5348275 未加载
评论 #5348112 未加载
rwmjabout 12 years ago
I remember when the Pentium F00F bug was reported, I tested it by doing:<p><pre><code> char main[] = { 0xf0, 0x0f, 0xc7, 0xc8, 0xc3 }; </code></pre> (and yes, my machine -- a Pentium MMX -- hung solid and I was rather shocked!)
评论 #5348364 未加载
kpsabout 12 years ago
<p><pre><code> int x = 'FOO!'; </code></pre> will <i>not</i> make demons fly out of your nose: it is not <i>undefined behaviour</i>. It is guaranteed to produce a value; the specific value is <i>implementation defined</i> (that is, one that the compiler vendor has decided and documented), but it is an integer value, not a demon value.<p>I'm sure, though, that someone sooner or later will be bitten by code like<p><pre><code> int x = 'é'; </code></pre> which is equally implementation-defined.
评论 #5348893 未加载
评论 #5350280 未加载
gatherknwldgabout 12 years ago
C's corners aren't very dark. It's a small enough language that it's easy to explore them. Things can get ugly when programmers decide to abuse the preprocessor because the language isn't complicated enough for them, but thankfully most C programmers have a distaste for such shenanigans. C++ is down the hall and around the corner, if you want darkness.
dysocoabout 12 years ago
Someone should do "Dark corners of C++".<p>Nevermind, it would take more than the Lord of the Rings triology.
评论 #5349092 未加载
评论 #5348685 未加载
wtracyabout 12 years ago
Very cool.<p>I remember hearing that the disallowal of pointer aliasing was the main reason that it was possible for a Fortran compiler to produce code that could outperform code from a C compiler: It allows the compiler to perform a new class of optimizations.<p>It would appear that the restrict keyword lets C programs regain that class of compiler optimizations.
评论 #5348173 未加载
copxabout 12 years ago
It is telling that these "dark corners" all seem harmless compared to what you can find in certain other languages which shall not be named.
评论 #5348834 未加载
评论 #5348093 未加载
grnabout 12 years ago
It's also worth pointing out that buffers passed to strcpy, memcpy, etc. <i>must not</i> overlap. Otherwise it results in <i>undefined behavior</i>.
评论 #5348850 未加载
评论 #5348341 未加载
评论 #5349097 未加载
optymizerabout 12 years ago
I wrote a compiler for a subset of C, and I'm happily aware of all of these 'dark corners'. That's why I would always recommend writing a compiler for a language if you _really_ want to understand the language.
jimmaswellabout 12 years ago
"What would be the smallest C program that will compile and link?"<p>Author got this wrong, that would be an empty file, which is what won the IOCCC for smallest self-replicating program once.
评论 #5349095 未加载
halayliabout 12 years ago
Just FYI, If you know C and you want to take it to the next level, then Expert C Programming:Deep Secrets is one of the best books out there.<p><a href="http://www.amazon.com/Expert-Programming-Peter-van-Linden/dp/0131774298" rel="nofollow">http://www.amazon.com/Expert-Programming-Peter-van-Linden/dp...</a>
shurcooLabout 12 years ago
Reading <a href="http://golang.org/ref/spec" rel="nofollow">http://golang.org/ref/spec</a> is such joy after having lived through C/C++ for the last many years. I still love C++, but if I can get away without having to use it, then I'm all for it.
shaneebabout 12 years ago
Just like everything else programming languages have evolved. From Assembly to Fortran to C to Java/C# (just saying, no exact sequence implied). I dont think the languages we have now, far from perfection they may be, would have been possible without the "dark corners" in the older languages. We learnt from them and made better languages. So I say show respect to the old languages, learn from them and keep improving languages/tools... Everybody is happy.
评论 #5348541 未加载
pjungwirabout 12 years ago
There is a wonderful book about the trickier parts of C called Deep C Secrets (with a fish on the cover :-). It is a great second or third book after K&#38;R.
评论 #5349656 未加载
nonpmeabout 12 years ago
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)?<p>(Sorry for of offtopic)
评论 #5348993 未加载
评论 #5348820 未加载
arihantabout 12 years ago
I am almost certain the pointer aliasing thing could be fixed by providing the proper optimization tag at compile time. I remember back in introductory systems classes, we saw mind boggling optimizations from GCC at O3 - the pointer example is so trivial it must be optimized by the compiler!
评论 #5349857 未加载
评论 #5349182 未加载
graycatabout 12 years ago
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':<p>First, what are malloc() and free() doing? That is, what are the details, all the details and exactly how they work?<p>It was easy enough to read K&#38;R, see how malloc() and free() were supposed to be used, and to use them, but even if they worked perfectly I was unsure of the correctness of my code, especially in challenging situations, expected problems with 'memory management' very difficult to debug, and wanted a lot of help on memory management. I would have written my own 'help' for memory management if I had known what C's memory management was actually doing.<p>'Help' for memory management? Sure: Put in a lot of checking and be able to get out a report on what was allocated, when, by what part of the code, maybe keep reference counters, etc. to provide some checks to detect problems and some hints to help in debugging.<p>That I didn't know the details was a bummer.<p>It was irritating that K&#38;R, etc. kept saying that malloc() allocated space in the 'heap' without saying just what they meant by a 'heap' and which I doubt was a 'heap' as in heap sort.<p>Second, the 'stack' and 'stack overflow' were always looming as a threat of disaster, difficult to see coming, and to be protected against only by mud wrestling with obscure commands to the linkage editor or whatever. So, I had no way to estimate stack size when writing code or to track it during execution.<p>Third, doing data conversions with a 'cast' commonly sent me into outrage orbiting Jupiter.<p>Why? Data conversion is very important, but a 'cast' never meant anything. K&#38;R just kept saying 'cast' as if they were saying something meaningful, but they never were. In the end 'cast' was just telling the type checking of the compiler that, "Yes, I know, I'm asking for a type conversion, so get me a special dispensation from the type checking police.".<p>What was missing were the details, for each case, on just how the conversion would be done. In strong contrast, when I was working with PL/I, the documentation went to great lengths to be clear on the details of conversion for each case of conversion. I knew when I was doing a conversion and didn't need the 'discipline' of type checking in the compiler to make me aware of where I was doing a conversion.<p>Why did I want to know the details of how the conversions were done? So that I could 'desk check' my code and be more sure that some 'boundary case' in the middle of the night two years in the future wouldn't end up with a divide by zero, a square root of a negative number, or some such.<p>So, too often I wrote some test code to be clear on just what some of the conversions actually did.<p>Fourth, that the strings were terminated by the character null usually sent me into outrage and orbit around Pluto. Actually I saw that null terminated strings were so hopeless as a good tool that I made sure I never counted on the null character being there (except maybe when reading the command line). So, I ended up manipulating strings without counting on the character null.<p>Why? Because commonly the data I was manipulating as strings could contain any bytes at all, e.g., the data could be from graphics, audio, some of the contents of main memory, machine language instructions, output of data logging, say, sonar data recorded on a submarine at sea, etc. And, no matter what the data was, no way did I want the string manipulation software to get a tummy ache just from finding a null.<p>Fifth, knowing so little about the details of memory management, the stack, and exceptional condition handling, I was very reluctant to consider trying to make threading work.<p>Sixth, arrays were a constant frustration. The worst part was that could write a subroutine to, say, invert a 10 x 10 matrix but then couldn't use it to invert a 20 x 20 matrix. Why? Because inside the subroutine, the 'extents' of the dimensions of the matrix had to be given as just integer constants and, thus, could not be discovered by the subroutine after it was called. So, basically in the subroutine I had to do my own array indexing arithmetic starting with data on the size of the matrix passed via the argument list. Writing my own code for the array indexing was likely significantly slower during execution than in, say, Fortran or PL/I, where the compiler writer knows when they are doing array indexing and can take advantage of that fact.<p>So, yes, no doubt as tens of thousands of other C programmers, I wrote a collection of matrix manipulation routines, and for each matrix used a C struct to carry the data describing the matrix that PL/I carried in what the IBM PL/I execution logic manual called a 'dope vector'. The difference was, both PL/I and C programmers pass dope vectors, but the C programmers have to work out the dope vector logic for themselves. With a well written compiler, the approach of PL/I or Fortran should be faster.<p>It did occur to me that maybe other similar uses of the C struct 'data type' were the inspiration for Stroustrup's C++. For more, originally C++ was just a preprocessor to C, and at that time and place, Bell Labs, with Ratfor, preprocessors were popular. Actually writing a compiler would have permitted a nicer language.<p>Seventh, PL/I was in really good shape some years before C was started and had subsets that were much better than C and not much more difficult to compile, etc. E.g., PL/I arrays and structures are really nice, much better than C, and mostly are surprisingly easy to implement and efficient at execution. Indeed, PL/I structures are so nice that they are in practice nearly as powerful as objects and often easier and more intuitive to use. What PL/I did with scope of names is also super nice to have and would have helped C a lot.<p>Eight, the syntax of C, especially for pointers, was 'idiosyncratic' and obscure. The semantics in PL/I were more powerful, but the syntax was much easier to read and write. There is no good excuse for the obscure parts of C syntax.<p>For a software 'platform' for my startup, I selected Windows instead of some flavor of Unix. There I wanted to build on the 'common language runtime' (CLR) and the .NET Framework. So, for languages, I could select from C#, Visual Basic .NET, F#, etc.<p>I selected Visual Basic .NET and generally have been pleased with it. The syntax and memory management are very nice; .NET is enormous; some of what is there, e.g., for 'reflection', class instance serialization, and some of what ASP.NET does with Visual Basic .NET, is amazing. In places Visual Basic borrows too much from C and would have done better borrowing from PL/I.
评论 #5349058 未加载
评论 #5348937 未加载
评论 #5350307 未加载
评论 #5349649 未加载
评论 #5349354 未加载
评论 #5349691 未加载
hamidrabout 12 years ago
That's fun. Cause I remember this "x+++y;" as a question in one of my university entrance exams!
评论 #5348156 未加载
homeomorphicabout 12 years ago
A very interesting read!<p>By the way, shouldn't the right hand side text on slide 7 (the final part of slide 7) talk about the pointers z and x, instead of the values pointed at? (Aside: How do I write "asterisk x" on HN without getting an italicized x?)
NelsonMinarabout 12 years ago
int x = 'FOO!';<p>Took me awhile to understand this; single quotes define single characters, and for some C decided to allow multiple character character constants but leave their value as implementation-defined. Discussion: <a href="http://zipcon.net/~swhite/docs/computers/languages/c_multi-char_const.html" rel="nofollow">http://zipcon.net/~swhite/docs/computers/languages/c_multi-c...</a>
JoeAltmaierabout 12 years ago
Fun!<p>Lots more ambiguities in C++. But a challenge to find them in C. My favorite: [] are just '+'
评论 #5348720 未加载
colandermanabout 12 years ago
Is there a way to disable the fade-in? It makes scanning impossible.
评论 #5348791 未加载
lysiumabout 12 years ago
What's the point in 'count up vs. count down'?
评论 #5351507 未加载
simarpreet007about 12 years ago
Ah this just made my day! :)
dakimovabout 12 years ago
I don't get it. What will happen if you violate the language semantics? They call it 'dark corners'? If you hit your head against a wall, it will hurt. Is it a 'dark corner' of life?<p>Overall, the presentation is very weak, like from a yesterday's graduate.
评论 #5348555 未加载
评论 #5349358 未加载
评论 #5348349 未加载