• gcc does not check out of scope names in unreachable code

      0 comments

    While attempting to write a small HTTP server in C, I copied some code over from a previously written C file and immediately noticed a bug.

    -- File httpd.c
    #include "../mynet.h"
    
    if(errno = EINTR) {
        //do something
    } else {
        err_sys("read error")
    }
    

    Yes it’s a stupid beginner mistake – typing the assignment operator instead of the equals check. The thread of execution would never enter the else block. I corrected it, but the interesting part came when I tried to compile it.

    cc ../mynet.c httpd.c
    

    mynet.c contains some handy helper functions that I’ve used in my other server classes. Guess what – the compilation failed with this message

    "httpd.c:(.text+0x6a): undefined reference to `err_sys'"
    

    I checked my header and the err_sys function was nowhere to be seen. If this function is missing, how did my other class (from where I copied this code) compile previously?
    After some fiddling around I put the assignment operator bug back, and guess what? The code compiled fine.

    Based on just these observations, we can conclude that the gcc C compiler ignored the unreachable (else) part of the code. It did not even check if the code inside the else block was legitimate. How far did this behaviour go? Let’s see.

    -- File httpd.c
    #include "../mynet.h"
    
    if(errno = EINTR) {
        //do something
    } else {
        mocha(); //Undefined function
    }
    

    This compiles fine.

    -- File httpd.c
    #include "../mynet.h"
    
    if(errno = EINTR) {
        //do something
    } else {
        asdf;
    }
    

    This correctly fails with an error.

    So syntax checks are being done in code that is known to be unreachable, but there are no checks for undefined functions. A bug? I would say yes. Google did not turn up much except this old link – http://compgroups.net/comp.lang.c++.moderated/could-if-else-avoid-syntax-checking-compile-time-unreachable-code

    SocialTwist Tell-a-Friend
  • Working through UNP

      1 comment

    As I wrote previously, I’ve been working through Richard Stevens’ Unix Network Programming (3rd Ed) Vol 1. It covers the basics of the Sockets API in UNIX and similar OSs.

    Unfortunately I’ve been able to devote time for this mostly on the weekends. This translates to slow progress because UNP goes into a lot of depth about everything. This is a good thing, but it also means that I’ve to reread and review the last few pages everytime I try to pick up where I left off. This does not really help when I’m trying to understand concepts in depth. So what’s the solution? I’ll try to do a bit atleast 3-4 days a week from now on.

    UNP is an amazingly detailed book – and as one of my colleagues said – “If you read that book properly, Stevens makes sure that there’s nothing left for you to know on the topic”. I agree.

    Stevens wrote his own wrapper functions over common socket functions and used them in all the code examples in the book. The wrappers handle all error codes and portability issues (like IPv4/IPv6). These are included in a header unp.h (available in the back of the book as well as online on http://www.unpbook.com/src.html).

    Some reviewers of the book gripe about this and say that this is an obstacle to learning the actual functions. But I think that there was no other way to do it without littering every example snippet with code for portability and error handling. The wrapper strategy makes it easier to follow the examples, and at the same time – as I found out – it makes you write those wrappers yourself. True, you can just include the unp.h header as you try the examples, but then you’ll never know what those functions are doing. I’ve found that creating my own header and writing the functions as I come across them, after looking at the book’s source code, works great. Most of them will end up identical to those in unp.h.

    I’m pushing the examples I’m trying out into github – it’s a scratchpad so not everything might compile.

    I’ve added a generic startserver function to my header – this takes a pointer to a function as an argument. The generic function starts a server socket (bind/listen/accept), forks a child when a client connects and calls the function that was earlier passed as an argument, abstracting out the actual serving part. The function pointer syntax was not hard to figure out – I’d read Peter van der Linden‘s algo on unscrambling declarations in C last week. Interesting how things add up!

    SocialTwist Tell-a-Friend
  • Falling through

      1 comment

    When I was studying for my CS degree, the programming language we were taught was C. To be honest, I didn’t code much C in college – just what was necessary to scrape through the lab assignments. I did stay up one night writing Tetris in C with 2 close friends for an internal contest, but such occasions were rare. Pointers? Grokked them, but I suspect it was a very shaky understanding. For the rest of my years there, it was C for all lab projects. I didn’t dislike C, but I did find it tough for a first language. So as soon as I got a chance, I set out to do some side projects in Java (atleast I thought was writing Java). That was the end of my relationship with C, because my first (and current) job post-college was and still is in a Java shop.


    Fast forward 8 years. The products I’ve worked on till now have been in Java. Serverside Java, Infrastructure Java, Applications Java. An appserver, a desktop app, a SaaS app. Abstractions, APIs, SPIs, Specifications, Javadocs, Objects talking to each other – it’s a satisfying, pleasant world if you like high level order.


    I made occasional forays into Python and Ruby for some side projects and scripting.


    But lately, I’ve been wanting to code in a really low level language. Yes, like C. Let me rephrase that. I’ve been wanting to write code where I can be as close to the OS as possible, learn bit twiddling hacks, make low level system calls. I’m not sure what this desire was born out of. Maybe 8 years of Java. Maybe wanting low level control over what I was doing.

    So I’ve ploughed through K&R the last couple of months. Bought Deep C Secrets. Regrokked pointers – properly, this time. Had a brief period of not knowing where to go after this, which resolved itself in the form of Unix Network Programming (Richard Stevens). I’m working through Vol 1 right now. It’s slow going at times, but I’m loving every moment. I’ve fallen through – the abstractions, the bytecode, the layers of objects – and reached the ocean floor.

    <In the background, the Toccata ends, and the Fugue begins.>

    SocialTwist Tell-a-Friend