|
|
|
|
|
|
| |
| |
|
|
|
|
| |
| |
|
|
Invisible <voi### [at] devnull> wrote:
> >> Oh, I have a far bigger "problem" than that: C is the number one
> >> language requested in job adverts. :-(
> >
> > I feel your pain because I hate C (but for different reasons than you).
> It's very popular for "kernel-level development" for some reason.
C is popular for kernels and device drivers because the machine code
a C compiler generates is simple, straightforward and predictable. After
all, C is a rather thin wrapper around assembly. Also things like type name
mangling in C object files is relatively simple and de-facto standardized,
which makes it easier to write dynamic code loaders and such.
Kernel development is almost as close to hardware programming as possible,
so the farther away from hardware-level programming you get, the more problems
you may encounter when things don't work as they should. Also many things
designed to aid in high-level programming, such as garbage collection, may
only get in the way in such low-level programming as an OS kernel or a device
driver.
--
- Warp
Post a reply to this message
|
|
| |
| |
|
|
|
|
| |
| |
|
|
> Now that's interesting.
>
> 1. How does it know which files depend on which other files?
It looks inside the files to see which other ones you have #include'd.
> 2. A header file is what defines what can be accessed from outside a given
> source file. Without a header file, how do you determine what's supposed
> to be public and what isn't?
The stuff in a header file is just as valid in a source file, so just put it
there. IN fact instead of doing a #include you could just copy and paste
that file and put it there instead. Just like #include in POV.
> To use Haskell, you need to learn something like half a dozen basic
> principles. After that it's just figuring out "OK, how the hell do I
> perform task X?" Learning C++ it just seems like learning feature after
> feature after feature, seemingly without end.
It's not like you need to know the whole of C++ (or even most of it) to
write even quite complicated programs.
Post a reply to this message
|
|
| |
| |
|
|
|
|
| |
| |
|
|
scott wrote:
> It's not like you need to know the whole of C++ (or even most of it) to
> write even quite complicated programs.
You do, however, need to know rather a lot before you can get started...
Post a reply to this message
|
|
| |
| |
|
|
|
|
| |
| |
|
|
Invisible <voi### [at] devnull> wrote:
> >> 1. How does it know which files depend on which other files?
> >
> > If you write an #include line, you create a dependency to that file.
> > It's that simple.
> True. But presumably if you #include a file that defines a function
> prototype, you also need to compile and link whatever file it is that
> contains the source code for that function?
Of course you have to add all the source files to the project. The IDE
then compiles and links them.
The dependencies are not for deciding what should be compiled and linked
into the final executable, or how the compilation should be done. The
dependencies exist simply to make compilation faster when changes are done
to the source files. If you have a 10-million lines-of-code program and
you modify one line, you don't want to re-compile everything. You only want
to re-compile the minimum amount necessary to get the updated executable.
That's what dependencies are for. This is all done automatically by the IDE
(or makefile).
> (Except for the OS header
> files; I have literally *no clue* how that works...)
System library implementations have already been pre-compiled and come
with the system (or the compiler in some cases). Often they are dynamically
loadable, but you can link them statically to your executable if you want.
Dependencies to most system libraries are automatically added to the
program by the compiler without you having to do anything about it. When
the dependency is not there by default, you simply have to specify which
system library you want to use in your IDE or by telling the compiler
(in the Unix side that would be those -l command-line parameters).
To put it in simple terms: In the Windows side that's where a program
depending on a DLL file comes from. A DLL is simply a precompiled library
(which the OS loads dynamically when a program needs it).
> True... But I'm still wondering how VS does this in the absence of
> header files.
Does what?
--
- Warp
Post a reply to this message
|
|
| |
| |
|
|
|
|
| |
| |
|
|
> True... But I'm still wondering how VS does this in the absence of
> header files.
The IDE has a list of source files in the project.
Post a reply to this message
|
|
| |
| |
|
|
|
|
| |
| |
|
|
>> True. But presumably if you #include a file that defines a function
>> prototype, you also need to compile and link whatever file it is that
>> contains the source code for that function?
>
> The dependencies are not for deciding what should be compiled and linked
> into the final executable, or how the compilation should be done. The
> dependencies exist simply to make compilation faster when changes are done
> to the source files. If you have a 10-million lines-of-code program and
> you modify one line, you don't want to re-compile everything. You only want
> to re-compile the minimum amount necessary to get the updated executable.
> That's what dependencies are for. This is all done automatically by the IDE
> (or makefile).
I see. So you still have to manually define what needs to be linked somehow?
>> (Except for the OS header
>> files; I have literally *no clue* how that works...)
>
> System library implementations have already been pre-compiled and come
> with the system (or the compiler in some cases). Often they are dynamically
> loadable, but you can link them statically to your executable if you want.
>
> Dependencies to most system libraries are automatically added to the
> program by the compiler without you having to do anything about it. When
> the dependency is not there by default, you simply have to specify which
> system library you want to use in your IDE or by telling the compiler
> (in the Unix side that would be those -l command-line parameters).
>
> To put it in simple terms: In the Windows side that's where a program
> depending on a DLL file comes from. A DLL is simply a precompiled library
> (which the OS loads dynamically when a program needs it).
As I understand it (i.e., probably wrong), it works something like this:
- You write foo.c that contains a function called foo().
- You write foo.h which simply states that a function called foo()
exists somewhere.
- main.c does a #include "foo.h"
- 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.
- 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.
What I can't figure out is what happens if foo() is actually a function
somewhere in the OS kernel. 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?
The way this works on the Amiga is that you can't just *call* an OS
function. First you have to look up its base address in a table.
Basically, memory address 0x00000004 contains a pointer to a table.
Every OS function has a unique ID which is an offset into this table,
which enables you to lookup the function's base pointer. And then you
can jump to it. All of which takes about two-dozen assembly
instructions... I have literally no idea how the hell you'd do it from C
though.
>> True... But I'm still wondering how VS does this in the absence of
>> header files.
>
> Does what?
Figures out what parts of the contents of a source file should be
accessible from other files.
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. (And for God's sake
remember to update the header file when foo() changes its type signature!)
Post a reply to this message
|
|
| |
| |
|
|
|
|
| |
| |
|
|
Invisible wrote:
> Couple that with a cryptic syntax
Say, how's that Haskell parser coming along?
--
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
|
|
| |
| |
|
|
|
|
| |
| |
|
|
Invisible <voi### [at] devnull> wrote:
> I see. So you still have to manually define what needs to be linked somehow?
How else is the compiler going to know which files are your source files?
By reading your mind?
> What I can't figure out is what happens if foo() is actually a function
> somewhere in the OS kernel. 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?
That's what dynamic linking is all about. That's why they are called
"dynamically linked libraries". The OS performs runtime linking when the
program is launched: It goes through the program and sets jump addresses
to their proper values.
And if the program uses a direct system call, it doesn't jump to some
address. It tells the OS "I want to make this system call" and the OS then
jumps there. The compiler (or more precisely, the system library the compiler
is using) knows how to tell the OS that.
> >> True... But I'm still wondering how VS does this in the absence of
> >> header files.
> >
> > Does what?
> Figures out what parts of the contents of a source file should be
> accessible from other files.
In C every global function which is not marked with the keyword 'static'
is accessible from anywhere. A function marked with 'static' is only
accessible from that same source file but not from anywhere else. (Yes,
reusing the keyword 'static' for this purpose is a kludge in the original
C specification.)
In C++ nameless namespaces are a cleaner way to achieve the same thing
(and then of course there exist completely different mechanics for class
member functions, which can be public or private).
> 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. (And for God's sake
> remember to update the header file when foo() changes its type signature!)
Being in a header file is not what determines whether the function can
be called from the outside or not. In C, the keyword 'static' determines
that.
--
- Warp
Post a reply to this message
|
|
| |
| |
|
|
|
|
| |
| |
|
|
>> Couple that with a cryptic syntax
>
> Say, how's that Haskell parser coming along?
Yes, because how easy a grammer is for a machine to parse is *totally*
related to how easy it is for the human mind to comprehend.
Go Google "natural language processing". ;-)
Post a reply to this message
|
|
| |
| |
|
|
|
|
| |
| |
|
|
>> I see. So you still have to manually define what needs to be linked somehow?
>
> How else is the compiler going to know which files are your source files?
> By reading your mind?
Well, that's what I was puzzled by, yes. You guys seemed to be
suggesting that you just give VS a bunch of files and it somehow "knows"
how to produce a runnable executable out of them.
> That's what dynamic linking is all about. That's why they are called
> "dynamically linked libraries". The OS performs runtime linking when the
> program is launched: It goes through the program and sets jump addresses
> to their proper values.
This implies that an executable file contains some metadata in addition
to the executable machine code itself.
> And if the program uses a direct system call, it doesn't jump to some
> address. It tells the OS "I want to make this system call" and the OS then
> jumps there. The compiler (or more precisely, the system library the compiler
> is using) knows how to tell the OS that.
I see. (I think!)
> In C every global function which is not marked with the keyword 'static'
> is accessible from anywhere. A function marked with 'static' is only
> accessible from that same source file but not from anywhere else.
Interesting. I never knew that...
Well, in that case it should be pretty simple.
> (Yes,
> reusing the keyword 'static' for this purpose is a kludge in the original
> C specification.)
>
> In C++ nameless namespaces are a cleaner way to achieve the same thing
> (and then of course there exist completely different mechanics for class
> member functions, which can be public or private).
Yes, yes, and yes. ;-)
Post a reply to this message
|
|
| |
| |
|
|
|
|
| |