RSS

Tag Archives: C

Programming Puzzle #1 Solution

This is solution to Programming Puzzle #1

So there’s a couple things going on here. They include trigraphs, strange pointer arithmetic, casting, single and multi-line comments, and general compiler abuse. Let’s take this apart step by step:

Trigraphs

Trigraphs were used several decades ago when keyboards then didn’t have all of the characters that we now have, such as curly braces, backslashes, etc. So, in order to encode these, three-character strings were used. Typically, the original trigraphs of C at least had a “??” prefix. (In C99, the notion of a standard prefix for trigraphs was removed). The ones I used in this program were ??/ (backslash), ??)(left square brace),  ??((right square brace), ??!(pipe), ??> (right curly brace), and ??< (left curly brace).

The first one is the most interesting. In C, the backslash character can be used to write strings that are too long to fit on a line (the only thing to note is that the continuation of the string must occur immediately on the next line, without spacing. Since this breaks code indentation, other techniques are generally used (such as string concatenation either through strcpy, strncpy, memcpy, or less traditionally, two literal strings right next to each other. (There are other ways too). However, since trigraph (and digraph) substitution is done in the pre-processing stage, this concept of breaking onto new lines works for anything! So, let’s take the original source code given and substitute all of our trigraphs in and fix indentation:

Caveat: GCC4 turns off trigraphs by default as they make reading code much more complicated if used obscurely. That’s the reason behind the “w/ appropriate flags” condition on the problem statement. To turn it back on, compile with -trigraphs.

#define define include
#define include define
#include <stdio.h>
#include <stdlib.h>
main(/*int, char*/)
{
   char* c;c = calloc(10, sizeof(*c))//c = "hello, world" ; #define int char
   ;int x=(sizeof(int)<<sizeof(c))+(sizeof(int)>>sizeof(*c)), i=* c;do c[++i]="0123456789abcdef"[x & 0xf];while(x>>=sizeof(i));
   for(;x|i;--i)putchar(c[i]);
}

That cleans up a lot of things. Now we see that there are actually comments in this code! In fact, I just threw several clearly visible phrases (like the string “hello, world” and main() arguments) to trick a casual viewer into thinking that the functionality of the program was different from what it actually did.

Macro Definitions

Interestingly, the first two lines do nothing at all. To realize why, note that the pre-processor only traverses the source once. So, if we had actually made changes, they would not be reflected fast enough (on the first pass) to be properly dealt with by the pre-processor. The compiler would then complain about these unknown words (if the pre-processor didn’t fail first, which it almost certainly would). So we can just remove those lines. Below is the next revision of the source code, with comments and dead code removed and further indentation fixing.

#include <stdio.h>
#include <stdlib.h>
main()
{
   char* c;
   c = calloc(10, sizeof(*c));
   int x=(sizeof(int)<<sizeof(c))+(sizeof(int)>>sizeof(*c)), i=* c;

   do
      c[++i]="0123456789abcdef"[x & 0xf];
   while(x>>=sizeof(i));

   for(;x|i;--i)
      putchar(c[i]);
}

Now this is looking much simpler. Let’s see if we can clean this up even more and then analyze the essential core of the program.

Sizeof Operator

This is a very simple part. The need for me to specify is a 32-bit OS is clear here: the size of pointers will be either 4-bytes or 8-bytes based on 32-bit or 64-bit operating systems. Now, I was sloppy in this program for assuming the size of ints and chars to be 4 bytes and 1 byte, respectively, but I don’t feel too bad since this was just a small puzzle, I specified the compiler and language specification, and the functionality of the program does not depend on those values except in one place..

Let’s substitute the numeric constants too and see where we arrive:

#include <stdio.h>
#include <stdlib.h>
main()
{
   char* c;
   c = calloc(10, 1);
   int x=(4<<4)+(4>>1), i=* c;

   do
      c[++i]="0123456789abcdef"[x & 0xf];
   while(x>>=4);

   for(;x|i;--i)
      putchar(c[i]);
}

Now we’re at the last step.

Pointer Arithmetic and Bit-Shifting

Now by using a piece of paper or a programming calculator, we can trivially see that 4<< 4 is 64 (0b100 => 0b1000000) and  4>>1 is 2 (0b100 => 0b10) to give int x = 66. Nice. Now on line 11, we are setting the value of x to be value of x right-shifted by 4 bits. The reason for this will become apparent in the following paragraphs. Finally, if we follow the logic of the program, we see that in the do-while loop, we are setting the number to be a number definitely smaller than itself each time. The exit condition for the loop is when the clause is false. In C, this is a zero. So, we see that the loop will break when x = 0. So what’s with that last for-loop? We are doing a binary OR with a zero value. It therefore has no effect and we are just checking if i is 0.

Now let’s deal with the main part of the program. What the hell is line 10 doing? This is where understanding the meaning behind the []-operator plays a role. To put it simply. this is often called “syntactic sugar” since it’s just a way to write an otherwise slightly more complicated expression. It’s important to realize therefore that a[i] == i[a] since both are just equal to *(a + i), in pointer arithmetic. However, indexing also works for literals in C. So, realizing that the expression x & 0xf masks off the last four bits of x, we now understand that all this is doing is setting the next character of the c array to the hexadecimal representation of the trailing nibble (four bits) of x. Thus, noting that we are actually printing the array backwards at the end since the representation is backwards, we see that all we’re doing in this program is printing out the hexadecimal representation of decimal 66, which is conveniently 42. Note that there is not newline character printed after this.

Conclusion

If you’re paying attention at this point, you’d realize that there’s no return type listed in the function header of main() nor is any value actually returned. Wait but isn’t main supposed to return 0? Well, the usual approach is to return 0 on success, although any number can returned on error. This is where we have abused our benevolent compiler. All functions with non-listed return types in the function header have return type int and if no number is returned at the end of main(), we automatically return 0. So everything is taken care of for us nicely.

This concludes the solution of the first programming puzzle. Maybe I’ll put up more of them in the future.

 
Leave a comment

Posted by on December 11, 2010 in Uncategorized

 

Tags: , , , ,

Programming Puzzle #1

Consider the following program written in pure C89 on a 32-bit OS:

#define define include
#define include define
#include <stdio.h>
#include <stdlib.h>
main(/??/
*int, char*??/
/)??<char* c;c = call??/
oc(10, sizeof(*c))//??/
c = "hello, world" ; #define int char
;int x=(sizeof(int)<<sizeof(c))+(sizeof(int)>>sizeof(*c)), i=??/
* c;do c??(++i??)="0123456789??/
abcdef"??(x & 0xf??);while(x>>=sizeof(i));for(;x??!i;--i)putchar(c??(i??));??>

Two questions (solve without computer):

  1. Does it compile (w/ appropriate flags)? [Tested on GCC 4]
  2. What is the output?

Just a few tricks, but shouldn’t be too hard to solve. I’ll give the answer in the coming days.

 
1 Comment

Posted by on December 6, 2010 in Uncategorized

 

Tags: , , ,

Fun With Vim

I freaking love Vim. And yes, I’ve used Emacs in the past (mostly as the recommended editor for a class I took last year – did that for a few days and then switched back to Vim while in terminal or opened up the SSH directory locally and used Gedit. (Also, Gedit is almost certainly the best and most powerful built-in GUI editor you will ever come across. With plugin support, it’s incredibly extensible. It was my favorite editor for a very, very long time too.)

Obviously, Vim’s power comes in its insane customization options. Basically every conceivable thing you’d ever want to do on a text file can be done with a collection of cryptic characters which become not-so-cryptic as you begin to understand the language of Vim. Seriously, hacking and playing with this editor is also as fun as actually using it to code.

But of course, as with all good things in the world, there are some annoyances. Not so much in Vim as in Ubuntu. Hey I love Ubuntu and use it almost exclusively, but it’s kinda boring that it’s always so late to get updates into the main packages. Of course, that’s the reason behind PPAs in the first place, but still.. Anyway, as you may have heard, Vim 7.3 was finally released a few weeks back and of course I wanted to play with it. Basically the thing I wanted most was CursorColumn, which introduced a vertical column at whatever character width(s) you wanted. This is really useful at times when you have code formatting rules such as an 80-character limit on lines. RelativeNumber, which displays how many lines away other lines are from your current line instead of a fixed numbering system starting at the beginning of the file, is also a cool feature sometimes on certain motions (e.g.: copy next N lines – which was a pain before). And file encryption was the last big feature in 7.3, but that’s something I’ll likely never use (at least from within Vim).

So I decided I couldn’t wait until Ubuntu brought 7.3 into it’s main packages (apparently it’s not happening until 11.04 😦 ), so I figured I’d compile it myself. This I merrily did and modified /usr/local/bin/vim to point to the newly compiled executable. And this worked great for a while.. until I realized I was rather naive when I did that and didn’t include all the nice flags that would have enabled such things as Python support in use with certain plugins. So I tried to include stuff that I wanted and recompiled except I kept realizing there was more stuff I wanted. This went on for a while until one day I discovered a fully functional PPA for 7.3 😀 (note, I really wanted the latest release on the day it was announced, so there weren’t any PPA or straight up debs that I could use on the first day that I came across). Win! For the record, here’s the PPA in question. Okay so after finding Software Sources in Ubuntu 10.10 (wow, in Software Center until Edit and inaccessible through menus? grr..), I updated and languished in Vim glory. Very gratifying indeed.

In any case, I just got that done and now I am happy. Also, the past few days of looking through Vim help and learning random stuff from the Internet (did you know that “K” over a standard C function will open up the man-page for it?!), I arrived at my .vimrc file below:

"""  Basic Configurations

set autochdir
set autoindent
set autowrite
set bs=2
set colorcolumn=80
set cursorline
set expandtab
set foldmethod=syntax
set foldminlines=3
set hlsearch
set laststatus=2
set mouse=a
set nocompatible
set number
set ruler
set shiftwidth=4
set showcmd
set showfulltag
set showmode
set smartindent
set tabstop=4
set wildmenu
set wildmode=longest,full
set wrap
set whichwrap+=h,l,<,>

""" Options

filetype on
syn on
au FocusLost * :wa

""" Python options
autocmd BufRead *.py cinwords=if,elif,else,for,while,with,try,except,finally,def,class

""" Hard tabs in Makefiles
autocmd FileType make setlocal noexpandtab

""" Theme options

set background=dark
set t_Co=256
colors mustang

""" Misc mappings and configs

cmap w!! %!sudo tee > /dev/null %
imap <c-c> <Esc>
imap <F1> <Esc>
imap jj <Esc>
nmap <leader> <space>
nnoremap <silent> <C-Left> :tabprevious<CR>
nnoremap <silent> <C-Right> :tabnext<CR>
nnoremap <silent> <C-t> :tabnew<CR>
nnoremap ' `
vmap < <gv
vmap > >gv

Some notes here:

  • Note that the first several lines under Basic Configuration are sorted alphabetically. There’s really no reason whatsoever for this except that I was far too amused that I could do this automatically. Basically you just do :set rnu for relative numbers. Then point your cursor to the first line, do N Shift-V, where N-1 is how many lines you want to select (after getting into Linewise Visual Mode), then :!sort which takes in the selected lines as input, uses the :! to execute shell commands, and of course the shell program sort to actually do the sort. I also realized this is possible by issuing N!!sort where N-1 is again how many lines I want to sort. The !! feeds in selected lines into the shell program and then the result is read back. Oh yeah and you can also do this with N Shift-V v_!sort. Basically, the point is that Vim is powerful.
  • Be sure to do set mouse=a if you want to enjoy the ability to switch tabs using a freaking mouse inside the terminal. Cool, though I rarely use it. Note that if you do this, it will override the built-in Copy/Paste functionality and I can’t seem to figure out how to directly copy text from within the terminal to the OS (or application, if on Ubuntu) copy buffer.
  • The options for set wildmenu and set wildmode=longest,full are the coolest things ever. So basically when you are entering commands, it will suggest completions on and then will iterate through the completions with each subsequent . Also, reverses through the list. This mimics the behavior of standard Bash’s completions and is thus extremely intuitive for me.
  • Another cool command is au FocusLost * :wa. As described in the Vim wiki, this basically will Write All files when the focus is lost. Very useful in my opinion.
  • The option set t_Co=256 enables colorful magic on XTerm terminals (and others). So instead of the usual 8 colors for syntax highlighting, you now get 256. Color-schemes look better, roses smell fresher, etc.
  • The line cmap w!! %!sudo tee > /dev/null % is an interesting hack that allows you to write files for which you don’t have permission when opened. It’s a pain to open a file, edit it, and then realize you don’t have permissions to write it. Sloppy approaches include writing the file to a temporary location and then copying back with permission, but that’s not nice. (One pre-emptive indicator would be to have a [readonly] flag in the statusline.) A solution is the above hack, which allows you to gain temporary super-user access and then write the file to it. Handy. This is a pretty popular hack found all over the Internet, so I’m not sure who to credit it too. I think the first place I saw it was on Command-Fu.
  • Yeah, so map jj to Esc. Just do it. You’ll see how much time you save and it will shock you incredibly causing unbounded, unexplainable glee. YMMV.
  • Finally, the last two lines which map < and > to <gv and >gv. This restores your selection after indenting or un-indenting. In my opinion, this should be the default behavior.
  • Finally, my Color Scheme is Mustang, slightly modified. I may post that up later. It’s an extremely awesome theme and my second most favorite one is Vitamin, also from the same guy. Both very cool.

I think I’ll just leave a screenshot of my Vim configuration as a final note:

 
2 Comments

Posted by on November 2, 2010 in Uncategorized

 

Tags: , , , , , ,

A Week Off

So I’m going to be taking next week off just so I have some more time to relax and refocus. I’ve felt that I never really got a chance to properly recharge between the end of finals and the start of my summer work. As I’ve said before, I just want some time free to think. More than anything, I enjoy having the time to do nothing in particular and not feel guilty about it either. My objectives for the week? I’d rather not specify exactly, but mostly I’m going to do lots of reading, some coding, some testing of Minefield, and clearing through all those links I’ve saved for reading at a later time.

I think now is also a good time to give an update on my research as I’ve completed about half of it or so I guess. So basically, the goal is to discuss the appliability of and to design a better resource allocation algorithm in a distributed computing system. Clearly the main problem is to figure out not only how to evenly distribute available resources in order to fully utilize the capabilities of the system, but also, on a local level, run each program as fast as possible. To accomplish this, it is not good enough to just give everyone an equal share – rather, you have to give each program the combination of resources that best fit its needs. Along a related thread of thought, we see as a natural consequence of this non-trivial allocation scheme that there exists some parts of the system – some nodes – are more heavily utilized, or more “popular.” But what is it that makes it so? These are the questions we are seeking to answer. Our approach is to look at the past for clues. So, we’re digging through many years’ worth of log files of usage in order to see how the popularity of nodes has evolved in the past. We are testing out several complex models of popularity metrics and seeing how well they match the data.

There are three of us working on this project and each of us are focusing on different aspects. For my part, I’ve been focusing specifically on how to extract pertinent data from the terabytes of textual log files in acceptable speed and how to best automate the task of actually finding relationships. I’ve decided to break up my work into many small programs that do different things and are tied together by scripts that automate as much as possible. Apart from modularity being good style, it also preserves sanity since this stuff can get pretty damn hairy.

There was one specific aspect that caught my interest in particular. The problem was tactfully posed by my professor as follows: let’s say we want to see how the temperature of water in a swimming pool and the height of the dive is related to how much pain the diver feels. Holding the temperature constant, we expect higher dives to hurt more but if the height isn’t too much, the relation may be weak and depend more on how you dive, etc. But conversely, how does temperature make a difference? At first glance, there’s no appreciable trend for a small range of temperature. But cross 32 degrees F and it’s a different ballgame. We strongly expect the height of the dive to affect pain felt and for it to hurt a lot more!

In this same, consider values of two seemingly independent data fields, one being the synthetic field of popularity and the other being a more tangible entity that deals with actual hardware. We seek to automatically find the ranges of the data that yield strong correlations.

In mathematical language, we seek to automatically perform a segmented regression on the data. Our final regression may be piecewise-linear, some crazy high order interpolated polynomial, or even non-parametric; but for our needs, this is at present not our concern. Thus, I chose to only look at the correlation coefficients. But there’s more than just one type: we are all taught Pearson’s coefficient, but other popular ones include Kendall’s Tau and Spearman’s Rho. Currently I’ve just implemented Pearson’s but this will almost certainly be replaced by Kendall’s. Why? Because linearity is not as importance as dependence in general. Having decided upon this, it was time to next decide how I was going to implement this in code. The main challenge was to automatically determine the relevant breakpoints that would yield the maximum correlations. There is a good deal of literature on this but in my preliminary search I only found papers that were either very marginally related to what I was doing or just too complicated, so I decided to implement a simple algorithm on my own.

I was writing this in C and so I grumbled about how I didn’t have my usual built-in data structures as in Java (grumble grumble) but I did have a decent ArrayList and HashMap implementation I could use (I miss my TreeMaps everyday…). Basically there are two parameters we wish to maximize: the correlation and the length of the segment. This need arises since a segment of one or two points will de facto have a correlation of unity and our data is certainly non-uniform. So, I thought of some kind of learning algorithm to accomplish the task and finally ended up with a simple algorithm that runs in ~2*N time (where ~ denotes tilde notation). Basically I start with some initial set of breakpoints evenly distributed along one axis. Then, I run a loop wherein I compare correlations of adjacent blocks. If their weighted sum of correlation and number of points in the block exceeds either block individually, I remove the middle breakpoint and coalesce the blocks. I recursively do this through all the blocks and then do the exact same thing in the reverse direction.

Now I have a set of unequal length blocks. I then copy all the blocks’ information into my ArrayList and sort by a custom comparator that compares the weight of the block, defined by: X*abs(correlation)+Y*(nelem_in_block), where X and Y are some constants.

In practice, this approach works reasonably well when the number of initial breakpoints is large enough. Besides, since we are only looking for heuristics, this does the job.

Now that that’s all done, I ran some tests on the data and the results are looking close to what we expected. When I get back, I’m going to tackle the task of tweaking and reworking the popularity metric to get even finer results.

But for right now, it is time to kick back and relax. Awesome.

 
2 Comments

Posted by on July 9, 2010 in Uncategorized

 

Tags: , , , , ,

Quick Update on Summer

I’ll write more later on but I just wanted to give a quick update on how my summer has been going. So I’ve started my research at Princeton about three and a half weeks ago and so far it’s going pretty well. Mostly it’s a lot of data analysis work and a fair bit of programming. That’s a very good thing. Honestly the more I think about it the more I realize that programming is what I love more than anything else. I’m effectively thinking about programming all the time anyway, always trying to look at the world through the lens of computer science (of what little I know of it) and so to have the opportunity to actually do it for the summer is quite cool. I’m working on servers running a variety of 64-bit Linux flavors, most of which have at least four cores and 8 gigs of RAM. The computational capacity of them is really amazing and the ability to run in parallel at acceptable speeds makes life easier. I’m extremely happy with the tools I’m using – straight manual Makefiles, gcc, gdb, and emacs/vim. As far as code is concerned, it’s mostly C, some Java, and very often Bash scripts with occasional AWK or Perl for quick things. For some reason I’ve found this setup more easy to work with than an actual high-powered IDE. Weird, perhaps, but I sure hope wherever I work in the future I will be afforded this same luxury.

The more I work with Linux, the more advantages I see. I was comfortable with Bash coming in this summer and I’ve learned even more after working exclusively with it. Linux feels like it was designed solely for the purpose of making a programmer’s easier and its done a great job at that. I’ve learned a lot more of Bash scripting now and I’m always amazed at how powerful it is. It’s an extremely useful language to know. For source control, I pretty much had the choice of deciding what I wanted to use and I chose SVN although I think I should’ve perhaps gone with Git. It’s been many months since I’ve used SVN but it was very easy to catch on again. It also forces me to be organized with my code and be more standardized so I’m not going to complain :).

For collaboration, I suggested we use Google Wave to keep a running to-do list and so far it’s working beautifully. It really is the best way to keep track of ideas (although I still maintain an ongoing to-do list on the whiteboard and on my Google Tasks because I’m weird like that). Checking off completed items is pretty damn thrilling – I love the feeling of making progress.

Apart from working on my current research, I’m also doing some light QA/Testing for Mozilla. I’m on the nightly builds (Minefield) on my Linux and Windows 7 partitions (though I use (Linux almost always). But I think that’s helpful here because there are far fewer Linux testers anyway. Mostly it’s just running Litmus tests, benchmarks, and giving feedback on UI/UX changes as they appear and/or break :). It’s a cool feeling to get daily updates and check out what new patches were made and to see the design process through the eyes of the developers. I’m also running on the dev branch of Google Chrome and there too it is interesting to witness the evolution of the interface and behavior. One day I imagine myself actually a developer at one of these companies, pushing out updates to millions of users… that’s something I like to think about everyday. I know it’s silly but I get a kick out of pretending that every commit I make has some tremendous influence. Maybe one day it will be so and all this is good preparation for that I guess :).

This summer my main goals are to of course continue my research but also to learn Python and master C++ properly. I have a somewhat adequate knowledge of C++ right now but I never learned it formally – I want to take this summer to actually learning the finer details of the language. Being that many, many applications are written in that language and that it’s widely the most popular language for programming contests too, it is certainly worth learning. As far as Python, I know that I won’t regret learning that. Seeing how much I’ve come to respect the power of quick and dirty Bash scripts, I know I’ll love the even greater power, flexibility, and ease of use of Python. A few of my friends are learning it too this summer, some for whom it is their first language and this further motivates me to learn it.

I’m going to be taking next week off from research for precisely these reasons among others. Princeton has really tired me out a great deal and I need some time to rest and regroup. I hope to take it a lot easier and to get started on learning those languages. I’ve also got to continue work on the Princeton Math Club blog. For that, I’m thinking of implementing the new Post Type feature that WordPress 3.0 brings. And for that, I need to polish up some PHP skills and get to work hacking away at the current theme. Looks rather straightforward so it shouldn’t take too long to do.

Okay so this post is freaking long and not quick at all. It also took quite a while to type out since I wrote it from the WordPress app on my Droid. More on that in an upcoming post. But for now, that’s about it.

 
1 Comment

Posted by on July 7, 2010 in Uncategorized

 

Tags: , , , , , , , , ,

Security Policy Implementation

This weekend has been taken up almost exclusively by coding (yet again :)). This time, I’m working on a project for ELE 386, also known as Cybersecurity. The task is to develop a working implementation of a well-known security policy in a way that can be used to update permissions and check permissions. I am implementing the Clark-Wilson model and building a multi-platform, command-line interface. Considering I started this about 36 hours ago, I think I’ve made pretty good progress. Normally, I’d write something like this in Java, just due to the ease of using built-in data structures (TreeMaps, HashSets, etc.) but the assignment kinda leaned towards C/C++ (yes, I know I can write my own, but I don’t have the time or patience to..). Seeing as I’ve just picked up C this semester, I decided to go with that as a challenge.

Yesterday, I hacked together the basics of control flow and some I/O (C89 doesn’t allow function overloading. what. -_-). The challenge here is that we are to assume that the user will be malicious; in fact, we will be trying to break each other’s implementations in the next part of the assignment. So, every single input has to be extremely meticulously validated before anything happens. In fact, I’ve completely decided against using scanf() or even fgets() for user-related I/O; I need finer control. So, I’ve decided to literally getchar() each character by hand, doing multiple checks on bounds and legality of inputs. Every input has a pre-defined upper bound and so far, it seems to be watertight. One problem that I encountered was figuring out how to get rid of extraneous characters in the stdin buffer (for example, if the user is asked for at most 3 characters and replies with 46 characters).  I tried a lot of different things and ended up with this approach, a slight adaptation from here:

void flushInput()
{
   char c = ' ';
   ungetc(c, stdin);
   scanf("%c%*[^\n]%*c", &c);
}

Essentially, this little function first creates an arbitrary characters (a space in this example), uses ungetc() to push the space onto the stdin buffer. Then, using a bit of formatted string ninja, scanf() reads in the space, skips everything that’s not a newline characters, and then skips the character right after that (the newline itself). I know it’s not the prettiest piece of code, but it’s faster than doing getchar() in a loop and checking for EOF.

Once I had crossed that hurdle, I was able to quickly get through a lot of other small issues. One source file quickly become 3 which quickly became like 9. The layout and refactoring that I started doing early really helps to keep it all sane. Last night, I also finally was able to glue in an MD5 hashsum implementation with my code, as I only want to be storing the hashes of the passwords instead of the passwords themselves. That ended up working pretty nicely and made my implementation stronger.

This morning I was able to write the database importer that loads the file into memory. I ended up going with an array of struct pointers, which in turn hold a linked list of struct pointers as my primary data structure. So far it’s working well and I’ll have to serialize this abstraction and write the exporter of the database back onto disk. Should be fun. In the meantime, I’ve gotta write some more code to validate queries, which can be rather long and complex. Did I mention I need to get this working by Tuesday? It’s gonna be a long night..

EDIT: One last note. Found an error in the Bryant & O’Hallaron book on page 611. The function prototype for execve() is listed as:

#include <unistd.h>

int execve(char *filename, char *argv[], char *envp);

However, the correct prototype is actually:

#include <unistd.h>

/* Note the braces on envp */
int execve(char *filename, char *argv[], char *envp[]);

Not a huge deal, but it’s an important function, so just wanted to point that one out.

 
Leave a comment

Posted by on April 18, 2010 in Uncategorized

 

Tags: , ,

The Start of Another Week

It’s late Sunday night which means this week has already started. But I’m not too worried because so far I’m off to a pretty good start, work-wise. I’m really glad I took the time today to be as productive as possible; I know that this will make getting through the workload this week much easier. The more I read CS, the more interested I become in it.

I got through 100+ pages of the Bryant book (this one), which I’m pretty proud of, because that stuff is hard. It took me a while to really understand what was going on and I can’t say I understand it all, but I get the overarching concepts pretty well. It’s pretty incredible how much a computer does even when interpreting a simple input from the user or even just a routine OS exception that a program throws. Reading about all the different ways a computer maximizes its output while minimizing its time taken, the key optimizations necessary to let programs run at acceptable speeds; I can’t help but wonder how these ideas ever first occurred to someone decades ago. Just to understand what they’re saying, after several levels of simplification, is a challenge for me. I’ve wondered for a really long time how the lowest-level interactions between hardware and software are dealt with. We’ve cringed over how messy such simple C programs that involved calls to malloc() and free(), whereas even these are very high level compared to how things are actually done. Of course, reading about Knuth’s contributions to the development of efficient malloc() implementations (of first-fit as compared to best-fit) have only served to increase my admiration of him. It’s magic, what these guys do.

 
Leave a comment

Posted by on April 11, 2010 in Uncategorized

 

Tags: , , ,