-1

When C code is compiled to an exe/pe/app, (from my knowledge) it is converted into machine code. This can then be run by a processor.

My question is, since this is very low level, it shouldn't make any calls to OS specific functions (as these will already have been compiled to machine code as well). So why can't it be run on different platforms, like Linux, Windows, OSX?

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
Melkor
  • 779
  • 1
  • 12
  • 29
  • 3
    First, the binary format is different so you need an appropriate loader. Second it may use libraries with different calling conventions. Third, the code in general DOES invoke OS specific functions and which ones are available and how to call them does depend on OS. `wine` on linux pretty much runs the windows code in native mode, emulating the necessary libraries and OS interfaces. – Jester Apr 27 '16 at 15:06
  • @Jester but wouldn't the linker add the assembly code from the OS specific functions into your main executable, so that it was just assembly that could be run on different platforms? – Melkor Apr 27 '16 at 15:20
  • 1
    The OS is not part of the executable, it is another layer, which has the ability to launch the executable and provide services. And the OS will be different on each platform, the compiler won't have a library of the all the OSes for all the different platforms anyway. – Weather Vane Apr 27 '16 at 15:23
  • some C is portable if using C libraries, but the backend implementation of the libraries is operating system dependent. The calls are to the operating system and the C library is not generic it is specific to the operating system underneath. Could it be done another way? yes, see JAVA or Python. Wouldnt be surprised with the gnu tools if you could write C that runs on an JVM which is then portable. – old_timer Apr 27 '16 at 15:26
  • 2
    C is generic from a source code perspective not binary. – old_timer Apr 27 '16 at 15:27
  • 1
    and then you have the problem of the myriad of differences in the processors over time, you can compile for the least common denominator perhaps... – old_timer Apr 27 '16 at 15:27
  • @Marchhill even if the linker included the OS services (which it doesn't), the hardware platforms still have differences (e.g., PC BIOS versus Mac BIOS) even if they have the same microprocessor architecture (e.g., x86). Then of course there's 64-bit versus 32-bit, etc. A 64-bit compiled app won't run on a 32-bit platform. – lurker Apr 27 '16 at 16:30
  • Does this answer your question? [Why do you need to recompile C/C++ for each OS?](https://stackoverflow.com/questions/61644911/why-do-you-need-to-recompile-c-c-for-each-os) – mmmmmm May 08 '20 at 11:25

1 Answers1

2

The premise of the question is based on a big misunderstanding about how computers work.

Compile a simple "hello world" executable. Disassemble it, or let the Godbolt Compiler Explorer do that for you.

Does it contain a copy of the library implementation of puts / printf? No. It's dynamically linked to libc so every program doesn't need its own copy of every library function it uses.

Does it contain graphics drivers that actually draw the text in video memory? No, of course not, and that wouldn't even be possible for a program that runs in a multi-tasking OS with memory protection: The OS can't let processes access the hardware directly; they'd be able to crash the computer or draw on each other's windows.

Instead, processes make system calls to interact with things outside of themselves.


Leaving all that aside, there are multiple architectures that don't understand each other's machine code. So even within the same OS, an x86 binary won't run natively on an ARM CPU.

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
  • 1
    There is a lot more to add: calling conventions (cdecl vs fastcall vs ...), binary formats (elf vs mach-o vs win32 vs ...), etc. – Leandros Apr 27 '16 at 16:41
  • 1
    @Leandros: I was trying to think of a close-reason for this question based on such a wrong premise; too broad might do it. I was going to leave a comment, but it was enough to be an answer. You're right: a complete answer would be a book. – Peter Cordes Apr 27 '16 at 16:49
  • I've downvoted not because the information is bad. The question is clearly broad (I downvoted it and recommended close for same reason), and I don't think it helps to answer a broad question with a broad answer (you do admit the answer could have been a book). A comment would likely have been better. I'd upvote this answer (if it was less broad) and was associated with a specific question. You could write your own question that is more specific and provide a specific answer that has some of this information in it. Your opening line is a bit antagonistic – Michael Petch Apr 27 '16 at 17:14
  • @MichaelPetch: Thanks for the comment on the opening line. Changed it to be hostile to the question, not the asker personally. (Asking a bad question doesn't make you a bad person.) This is only "too broad" because it would take a huge amount of info to correct the mistaken understandings that led to the question. The question itself seems fairly specific from some points of view. Understanding the answer requires reading the wiki pages I linked to, but I think it does answer it fairly directly by saying "no, that's not how stuff works", without getting into other portability problems. – Peter Cordes Apr 27 '16 at 17:33
  • @MichaelPetch: I didn't upvote, but I could see the question possibly having future value for the site. Anyone who already knows the answer can see from the question title what this is about, so cluttering search results isn't a huge issue. If other people think this Q should be deleted, I have no problem deleting this answer first to enable that. – Peter Cordes Apr 27 '16 at 17:35