ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
I'm one of those people who hates to learn how to USE something without knowin how it WORKS (or at least having the means to know, ex: a book or the source code).
Having said that, I'm starting to feel REALLY uncomfortable with the C Programming Language. I'm a C Programmer, but I'm starting to raise some questions. I'm particularly interested in knowing how the a Computer and Operating System works, so I only move downward in the programming hierarchy.
So I figure: A C Program is generally cross-platform. My guess is that there are alot of times when the program has to interface with the OS, such as when working with streams/file descriptors (ex: std in/out/err), files (different files systems, the OS has to manage that- also, Windows uses drive letters and UNIX uses slashed, somehow the OS has to work with those differences w/o modifying the C code), and memory management (ex: the System knows where the memory is located and can restrict the program from accessing certain portions in certain manners). These are all assumptions, but I'm sure they HAVE to be true or else how can you possibly manage to do these things AND have the Operating System work correspondingly at the same time? Surely... the two have to interact somehow
So one big question:
I am aware that C Programs are generally dynamically linked, so they can run on a particular C Library on the PC from which is runs, but can a statically linked program run on other systems???
But then again, for example, you have functions to read/write to files- does that mean that you cannot use them without first having an operating system? (ex: you are designing an OS and need to use these functions).
And Another: how exactly does a C Program interface/interacts with the OS? (if it does, that is- like I said, it could just be dynamically linked)
Which raises another question: Does an operating system have to "comply" to some sort of an interface to allow C Programs to run in that operating system
Now... you can skip those questions if you can answer this: The Official C Standard is published in a book called "The C Standard"- does the standard define this interface/interaction?
As you can see I am VERY curious and it's been killing me to know these questions. More than likely I will obtain a copy of the standard so I can see exactly how the two interact. But I was hoping that the awsome people here on LinuxQuestions, who have always been helpful before, could save the hassle and at least give me a sense of direction (ex: tutorial or book that explains the interface/interaction between program/OS)
"So one big question:
I am aware that C Programs are generally dynamically linked, so they can run on a particular C Library on the PC from which is runs, but can a statically linked program run on other systems???"
The key to most of your questions is that the compiler produces binary code for a particular CPU and produces calls which meet the interface specifications of a particular operating system. Whether a program is statically or dynamically linked is independent of which CPU and OS the binary will run on.
"And Another: how exactly does a C Program interface/interacts with the OS? (if it does, that is- like I said, it could just be dynamically linked)"
The compiler creates a binary which, when it calls upon the OS for a service, conforms to the OS specifications of how data is passed through the call.
"Which raises another question: Does an operating system have to "comply" to some sort of an interface to allow C Programs to run in that operating system"
It is the other way around. The call for an OS service has to comply with the OS interface.
"Now... you can skip those questions if you can answer this: The Official C Standard is published in a book called "The C Standard"- does the standard define this interface/interaction?"
No, it defines how the source code looks. The operating system works to a different set of standards. In the case of Linux this is POSIX specifications number something or other.
"the compiler produces binary code for a particular CPU and produces calls which meet the interface specifications of a particular operating system."
so are these calls the same between other operating systems? Ex: how can a program compiled in Linux run in Windows?
"[the program calls] upon the OS for a service,[and] conforms to the OS specifications of how data is passed through the call."
If the calls work from one system to another, then does the way the OS "picks up" the calls (more or less) the same? how exactly does that work?
"The call for an OS service has to comply with the OS interface."
Like my previous questions above- then how can one program compiled on one OS run on another?
And lastly... if the C Specification does not define how the Program and Operating System interact with each other, where can I get this information?
Sorry if I'm being a pain, but I need to know where I can get this information. Even if (and most likely) I am not ready to even understand half of how all of this works, I would feel really comfortable if I could have sources that explain this interaction, and how static/dynamic linking works.
In general, I'm trying to learn how a program works PERIOD
Originally posted by TGWDNGHN
so are these calls the same between other operating systems? Ex: how can a program compiled in Linux run in Windows?
I think that's exactly the mistake you are making when thinking about this. A program compiled in Linux cannot run in Windows. That is, unless you run it inside some Linux-emulator for Windows (e.g. cygwin). But that's a differnet story...
C is cross-platform only in the sense of source code. That means (in theory) that when you have C-sources you can compile them for Linux, and the resulting executable, binary code will only run on Linux, and not even on Linux for a different type of CPU.
C-source is cross-platform. The executable code generated by a compiler is not.
Quote:
Like my previous questions above- then how can one program compiled on one OS run on another?
It can not.
That is for example what makes Java special: When you compile a java program, you get (sort of) binary executables that run on many CPU-type / OS combinations. Java executable code is code for a CPU-OS combination that does not even really exist. It only exists in design, in software. remember you cannot run a compiled java program without an emulator for that non-existant "Java Vitrual Machine". Those "emulators" (virtual machines) themselves are written in C or C++ (I assume) and need to be compiled/linked seperately for every distinct OS/CPU Java supports. (just remember you need to choose whether you download JVM for Windows or Linux, or Mac,..)
Quote:
And lastly... if the C Specification does not define how the Program and Operating System interact with each other, where can I get this information?
I the programmer's documentation for the Operating System. (i.e. man pages, readme's, OS-sources, books about it)
Briefly:
1. The C standard will tell you WHAT the language is supposed to do (define its syntax, constructs, etc. The C Standard will also give you an idea of WHAT library functions you can expect on a conforming implementation (for example, you can reasonably expect to be able to find a "printf()").
The C standard will *not* tell you HOW any of this magic is implemented.
2. If you're interested in how a program (*any* program, not just one that happens to be written in 'C') interacts with the operating system - and if you're interested just what an "operating system" is, and how it works - there are innumerable good books. The following come immediately to mind:
3. Perhaps even more interesting, however, might be for you
to explore assembly language. For example, write a little 'C' program
that adds "2 + 2" and compile it with "-S" to get the assembler output.
Or write a more complex program (with loops and if/else blocks, for
example, and compile with "-S" and different "-OXX" optimization flags,
to see how the compiler translates the code differently, to do things
"faster" or "more compactly".
Or, if you have the luxury of different kinds of workstations (maybe you
have a Solaris SPARC or a Mac PowerPC), try "gcc -S" with different
architectures.
Ok so lemme get this straight. I have a VERY basic program like the following
#include <stdio.h>
int main()
{
printf("hi");
return 0;
}
I compile it on Linux (statically or dynamically, either way).... and it won't work in Windows? It mean, it doesn't use anything Linux-specfic...
Plus, theoretically speaking, suppose I use the same operating syste (ex: Linux) but am using a different C Library than the one it was compile with (ex: compiled using glibc, ran used "myclib")- will that work? I mean sure, the way the functions are defined are different, but they have the same input and output so regardless of how it works "under the good"- shouldn't it still run?
I been looking into a little, I think SOME of my questions are more directed at linkers and loaders... gonna do some reasearch. Iwont bother asking questions on those until I become a little more educated on the subject.
I compile it on Linux (statically or dynamically, either way).... and it won't work in Windows? It mean, it doesn't use anything Linux-specfic...
(emphasis mine, of course)
No, it won't work, because it does use Linux specific routines. Your call to printf() has to be expanded. The C language standard only specifes whether printf() exists, what arguments it accepts, and how it should behave. The standard makes no reference to how the function should be implemented; just so long as it responds correctly. As an example, if I were to tell you "Meet me at the bar on 5th street at 3:00", I've made no requirement on how you get there. You could walk, drive, ride a bus, skydive, whatever. I've only told you what I expect the end result to be: you being present at the bar.
So Windows and Linux are free to implement those functions in any way they see fit, and they have to introduce differences. The fundamental purpose of the OS is to control access to the hardware. By calling printf(), your program wants to access the screen. So your program has to make requests through the OS to get permission to access the screen, and then to tell what you want the screen to display. In order to do all that, the program has to play by the OS's rules. Those rules are defined by API's. Each OS is different in what they require each program to do.
So that's why even a simple program like you gave will not be cross-platform. Make sense? Or did I just confuse things?
I already understand how C is a language by specification rather than "this is the code, use it".
What I didn't understand was how it resolved some of these issues while being cross platform...
so THATS why they are normally dynamically linked- staticly linked programs require the use of a very particular C library- which is provided by the Operating system
I understand now... it all makes sense... I would just like some verification before I go screaming Eureka.
And if I am right... then my next topic to tackle is linkers and loaded (I found an online "draft" copy of "Linkers and Loaders" online, better than spending tons of money for a book less than 300 pages)
Yes, you're basically right if you mean that the C language specification is ... well, a *language* specification (and not a *binary* specification, aka an "ABI"):
If you're interested in how a "program" (some "bag of of executable instructions") actually "does stuff" (requests services of the operating system: including the ability to load and execute on the CPU) you should really consider at least borrowing a copy of Tanenbaum (or something like it) from your local library).
And finally, I'd strongly urge you to consider looking at assembly language: which is how "software constructs" (the stuff that the C specification - or ANY programming language - is made from) are mapped to CPU instructions. Assembly is where software meets hardware - I think you might find it enlightening.
IMHO .. PSM
PS:
If you're really interested in linkers and loaders, I think you can satisfy your basic curiousity here:
The basic advantages of dynamic linking are:
1. It can save space
2. It can permit greater flexibility
In general, neither a shared library nor a static library built for one architecture can be used on a different architecture - no more than an executable built for one architecture can be run on another.
Just to possibly clear up a bit on static and dynamic linking...
If you were to static-link a program on a Linux machine, you could likely move that program to a large number of other machines and have it still work. The reason for this is all that API stuff is included in the executable itself. Essentially, the program is self-sufficient. Since those APIs are Linux-specific, the application won't run under Windows.
Contrast that with dynamic linking. The purpose of dynamic linking is to save space. Most programs need access to a common set of utilities and/or APIs. It doesn't make sense to have each program have its own, personal copy of those routines. So somebody said, "Hey, why not leave that stuff out, put it in a common area, and tell the program where to go find the stuff when it needs it" So now, the program is split into (at least) two files. The program itself, and the shared routines (a library). A dynamically linked Linux program can move between Linux systems as long as each system has roughly the same version of the library the program needs and is located in the same place. It still can't run on Windows though. If you think about it, it makes sense. The program needs to access a file containing the library routines. So what does that imply? The program needs to make OS calls to read information from disk. OS calls are specific, and that means the application is limited to Linux-only.
To paraphrase: Both statically and dynamically linked apps need to be run under the same OS. Static apps can be run under a larger number of machines than dynamic; it's a trade-off for the benefit of saving disk space by sharing the libraries.
I never bothered to compile a program on Windows/Linux and run it on the other system. Just did, and I understand what happened now
I realized what all this means when I ran "file myc" and saw the output
I've just been denying the possibility that the compiled output would be "propreitary" to the computer's C libraries....
*sigh* well I guess it is true... but at least you can recompile it for different systems without modification... for simple programs anyways (yes, I am aware that for system-specific functions you might need a complete overhaul of a program's source code to port it over)
well, thanks anyhows guys- now I am truely enlighted (I think )
Basically, different systems run and load different binary formats. In Linux you have stuff like a.out, ELF, COFF, etc. In Windows you have Win32 binaries, and in the old days DOS and Win16 binaries...
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.