Of system calls and references

I have been mucking around with low-level system programming recently. I must admit, for someone who has a little C knowledge and is used to the glossy GUI of Windows, UNIX and System programming can be…messy to say the least.

Interestingly, most system calls have the following format

void sys_call (int * ret_val)

instead of

int sys_call ( )

Because of this, programmers have to declare a variable for storing the return value from a system call rather than use it directly in computations. This seems counter-intuitive and didn’t really make sense to me for a long time. I checked in many places on the Internet hoping I could understand why this paradigm was chosen but in vain.

Finally, I believe I have solved it!

This paradigm has to do with the user space and kernel space concept of the kernel. System calls provide the interface between these two spaces. The idea is that the kernel will have all permissions to access, modify, create and delete files and data in memory. Whereas, the users have limited permissions.

When you use the void sys_call (int * ret_val) way to use syscalls, You are effectively asking the kernel to do something and put the return value in the memory address (pointer) passed to it by the program. Since the kernel has the access to all the memory addresses, this has no problem.

However, when you use the int sys_call ( ) way. You are asking the kernel to do the computation, allocate a memory address to store the value and then send back the value.

It’s important to understand that UNIX comes from a time when memory was precious and I/O was  terribly, terribly slow. Hence they would try to make it as efficient as possible.

The return int way of doing sys_calls has the overhead of actually allocating a memory in location;copying the data onto this memory location and when returning from the method, copying it onto the left hand side of the expression.

Whereas in the void way, you just have to copy the data onto the memory location. Since RAM was constant time lookup, this took the same time irrespective of the memory address, be it kernel or user space.

That was pretty cool trick to optimize for a problem long forgotten.

Nested Functions in C

Yes, you read the title right. No, I’m not crazy , OK maybe a bit (no pun intended). Maybe I’m sleep deprived, I honestly don’t remember when was the last time I had a good night’s sleep but it is true, C does support nested functions, All that you learnt about C was wrong (Gasp!!) Don’t trust me? Fine, go ahead and try the following code out.

         #include<stdio.h>

         int main()
         {

           void foo () {}return 0;

         }

  GCC compiles it without a hitch. See, I told you! (again, no pun intended)I search around and figured out that ANSI ( C99 ) does not allow for nested functions. However, an addon for GCC provides support for it. I haven’t checked out its scoping rules or made any progress along that path. Do let me know if you find this out.

K THNX BYE

Pass-by-Reference in C

Unlike modern programming language, C has always been mysterious to even the most experienced of developers.
There’s always some feature of C that will surprise you even when you’re sure you know it inside out.

This is because C was written during a time when men were men and wrote their own operating systems in machine language.

So it was quite common for the creator of the language to put in quirks that made sense only to him. No one back then thought computers
would become common place.

So when the digital era kicked it, UNIX and C were behind its success, pushing it even further.

And C has faithfully carried forward these quirks to this date and I’m surprised every time I discover one.

Here’s an hypothetical, an interviewer tells you “C has only pass-by-value” , how would you support his argument?

It’s your first interview, and you’re already Stephen mcSweaty-Pants and he throws you this bouncer.

Quick! Think!!

Consider the following code snippet

void foo ( int * bar, int * baz)
{

//Do Something
}

You show this code to him and point to the header, pointers!!
you will be passing references to integer variables, surely this is pass-by-reference?

He still insists that C has only pass-by-value, you now think that he’s gone mad and that you probably won’t land this job.

Then he tells you consider how you would call the function

int x,y;
foo( &x, & y);

Now take a long look at that second line.

“Yeah, I’m passing references to x and y as required”

True, but try elaborating it a bit more (no puns intended)

“You are passing the VALUES of the memory address at which the values are stored”

BINGO!

To elaborate, the memory addresses of the actual parameters are copied onto the locations pointed to by the formal parameters
and and then the evaluation occurs.

So even when you’re passing references, you’re passing values of the addresses, which is effectively pass-by-value 🙂

Question: So how would you pass by reference in any language?

Turns out, Pascal supports pass by reference by using the var keyword.

procedure swap ( var x: integer, var y : integer);
var z : integer;
begin
z :=x; x:=y; y:=z;
end;

In Pascal, a formal parameter becomes a synonym for the location of an actual parameter.
keyword var is used to indicate this.

Inspired by and Pascal code snippet from “Programming Languages : concepts & constructs, Second edition” by Ravi Sethi