POV-Ray : Newsgroups : povray.off-topic : Tell me it isn't so! : Re: Tell me it isn't C Server Time
9 Oct 2024 13:12:56 EDT (-0400)
  Re: Tell me it isn't C  
From: Darren New
Date: 22 Jul 2009 11:55:03
Message: <4a673657@news.povray.org>
Invisible wrote:
> I see. So you still have to manually define what needs to be linked 
> somehow?

Lets just say I'm working with source files right now where the line used to 
compile the file takes up more than one screen of text in the editor.

> - You write foo.c that contains a function called foo().

OK. A function *definition*.

> - You write foo.h which simply states that a function called foo() 
> exists somewhere.

A function *declaration*.

> - main.c does a #include "foo.h"

Which is exactly the same as if you had copied the text of foo.h into main.c.

> - When main.c is compiled, it produces main.o, which contains several 
> references to a foo() that should exist somewhere, but we don't know 
> where yet.

No. Only if main() actually calls foo().

> - The linker takes main.o and foo.o, and replaces every jump to foo() 
> with a jump to an actual machine address. The resulting program is 
> actually runnable.

Sort of. That's called "linking." Then there's "loading", which is when you 
put it into memory and *again* adjust a bunch of addresses.

> What I can't figure out is what happens if foo() is actually a function 
> somewhere in the OS kernel. 

It isn't. The read() function in C, for example, is in the C runtime library 
(glibc or uclibc on Linux).  The linker always searches that library as part 
of the linking process (unless you're doing something funky like compiling 
the kernel). The read() function in that library is written in assembler 
(because C is really not very useful for this sort of work) and that 
assembler code copies items off the stack into machine registers and then 
invokes an assembler instruction that causes the CPU to set certain flags in 
the CPU registers that control permissions, change memory maps, and 
eventually winds up branching to a particular address in memory which the 
kernel has previously set to be a branch instruction to the code to handle 
read().  So read() is normal, except it's in a library the compiler always 
searches and contains assembly language.

> Presumably in each version of the kernel, 
> the base address of this function is going to be different... so how the 
> hell does the linker know what it is?

It doesn't. It executes a machine-code instruction that's essentially a 
software interrupt. (That's why you see things like DOS functions being 
described as "Int 21h" functions.)

It's an instruction that invokes an indirect branch.

> The way this works on the Amiga is that you can't just *call* an OS 
> function.

There's no memory protection or kernel mode on AmigaOS. It can't be multiuser.

> Like, if aux.c contains foo(), bar() and baz(), which of these should be 
> available from elsewhere? Normally if you only wanted foo() to be 
> public, you'd only put foo() in the header file.

Header files are 100% orthogonal to visibility. You're being confused by 
convention.

If your program defines foo(), it's visible. I.e., if you write
int foo() { ... }
then foo is visible in any source file holding that text.

If you write
extern int foo();
then foo is visible in any source file holding that text, but if you invoke 
it, you need to define it (see above) somewhere at link time.

That's your two choices.

When you actually call foo() from inside some other function, it has to be 
visible. (Actually, the C standard says it gets a default declaration, but 
nobody relies on that, because it was such a bad idea.)

> (And for God's sake 
> remember to update the header file when foo() changes its type signature!)

And for God's sake, remember to include the header file where you invoke it.

It hasn't anything to do with header files. You could build a whole OS with 
no header files. But if you changed the defintion of foo(), you'd have to 
find every file with an "extern int foo()" and change it to "extern long 
foo()", which is why people put them in include files.

-- 
   Darren New, San Diego CA, USA (PST)
   "We'd like you to back-port all the changes in 2.0
    back to version 1.0."
   "We've done that already. We call it 2.0."


Post a reply to this message

Copyright 2003-2023 Persistence of Vision Raytracer Pty. Ltd.