How exactly is portability of a language like C is determined? I've learned that compilers are ISA specific. If this is true, how is C portable? Or is it that just the source code written in C is portable but not the executables? Aren't the executables ISA specific for examples applications for x86 are separate from the applications for Apple (assuming Apple uses Motorola/PowerPC microprocessor)?
7 Answers
is it that just the source code written in C is portable not the executables?
Correct. Some people call it write once, compile everywhere.
http://en.wikipedia.org/wiki/Write_once,_compile_anywhere.
The other alternative is write once, run everywhere. Java is a good example of this.
http://en.wikipedia.org/wiki/Write_once,_run_anywhere
And even though you can achieve partial cross platform portability, you should never expect your code to run everywhere without modifications.
-
C source code not portable to different compilers or ISA's or OSes without quite a bit of extra-lingual shennanigans. Simple things like the size and alignment of standard types are not standard in C, so porting software that will exchange data with other instances of itself can be quite challenging. Refer to GNU Autoconf/Automake for a (possibly obfuscated) example of the hoops C programmers will jump through to get portability. May 16, 2011 at 23:33
-
3@TimWilliscroft: Portability problems are typically caused by non-standard libraries and bad programming practices; and are not caused by C or its standard libraries. A simple example would be using a non-standard GCC extension or failing to correctly serialise/de-serialise data for IO.– BrendanMar 12, 2013 at 6:06
It's not just ISA specific. For example you ask:
applications for x86 are separate from the applications for apple?
Yes, they are, even though Apple uses x86 hardware. C binaries are architecture and operating system specific.
-
1@Steven314: Your comment is a tangent. It has nothing to do with whether hardware is standard or not, and everything to do with the fact that OS X has a different binary format (Mach-O) than that of, say, Linux (typically ELF).– mipadiMay 16, 2011 at 18:14
-
@Steve: EFI vs BIOS only matters for booting and OS internals; the hardware architecture, which is the CPU instruction set is same, because it's same CPU.– vartecMay 16, 2011 at 21:34
-
Comments deleted, mainly because I should never have included the mac thing in the first place. My mention of ABI (Application Binary Interface) and call conventions may still be relevant (a third item to add to "architecture and operating system"). They aren't hardware relevant, except in that ABIs tend to be designed for particular architectures (e.g. available registers), but they are relevant to binary portability. This isn't a file format issue - ELF is used on Windows and Linux (by gcc), but you probably can't take an object file from one to the other.– user8709May 17, 2011 at 0:58
-
@vartec you said C binaries are operating system specific too, is it because O/S itself is ISA specific, thus C binaries become O/S specific indirectly?– KawaiKxMay 17, 2011 at 1:53
-
@Saurabh - all native executables are OS specific, because the OS specifies the file format. Also, a C standard library must implement many functions by calling the operating system, so even if the file format were standardized, the code itself couldn't run on another OS. This is standard for languages that compile to native code, as opposed to some virtual machine code such as the JVM (Java Virtual Machine). It is possible to compile C for a virtual machine, but never done that I know of. LLVM comes closest, but is intended as a compiler back end - not a compile-once-run-anywhere environment.– user8709May 17, 2011 at 5:04
is it that just the source code written in C is portable not the executables?
Exactly. You need to recompile your C program on every platform. C compilers generate machine code which is portable only to a very limited extent, between machines of the same processor/memory architecture and OS. That is why you see different binary distributions of multiplatform apps (e.g. browsers), such as "Linux 64-bit Intel" or "Mac OS X 32-bit PowerPC" (OK, the last one is just an illustration, I know Apple switched to Intel a few years ago :-).
Most of the question has been answered but I'd like to add than durability is another thing you might have to take in account.
For example, JAVA can be written once and run on any platform where the VM (today, it's called "Runtime Environment"). But another advantage is that you can run Java 1.1 code from 1995 in your 2011 machine. Which is not possible if your code was compiled on i386 and you try to run it on your AMD64 architecture.
You get the improvements of the virtual machine itself as well.
Then, I would say that in general, going from the least portable to the more portable languages you would have: Assembler, low level compiled language like C, then C++, then interpreted languages or the ones that run within a virtual machine.
I'm not really a Java defender, at least not for the language nor the community for example, but it's the way to go if you're looking for portability and the least performance loss compared to C.
Good answers about write once compile anywhere.
People like to think about C as a portable language because of its popularity and the high probability of a C compiler being available for future target platforms. Another factor is the standard library which helps with common programming tasks in a platform independent way.
So I would say the portability of a language is determined by:
- Level of standardization.
- Availability of compilers for different platforms/architectures.
- Depth and breadth of portable libraries.
Realistically though almost any complex C application will require some work to move over to a new platform due to hardware or operating system dependencies. That process is known as porting.
"Portability" has multiple meanings. With respect to C, it means the following:
Compilers have been implemented for C for a wide variety of hardware and operating system platforms, which was a Big Deal back in the early '70s;
There is a universally agreed-upon standard for the language itself, as opposed to each compiler implementation recognizing a slightly different variant of the language (again, a Big Deal when C was first designed, as there were multiple variants of languages like Pascal and BASIC that weren't universally recognized);
Because of this standard, conforming code will produce the same behavior when compiled on different platforms.
The source code is portable, but a new binary has to be generated for each target.
Note, however, that C source is rarely "trivially" portable; most applications require you to go beyond what's defined by the language standard, using extensions that are unique to a particular platform, so in practice source code isn't 100% portable.
Note, however, that C does leave quite a lot up to the implementation. The exact sizes of various data types, the behavior on overflow, etc., are all up to the implementation; the standard provides the minimum requirements that an implementation must conform to, but the implementation is free to go beyond those limits.
Whatever ISA is, C isn't ISA specific. I assume you're not referring to the now-obsolete slot for PC extension cards.
There are standards-compliant C compilers for very many platforms, and as long as you use fully standards-defined language features in your source code, you should be able to compile it on any C compiler for any platform.
However, one gotcha is that the C standard leaves a lot of behaviour of features as either implementation defined or as undefined behaviour. This is done to make the C language more generally useful for low level programming, avoiding cases where some precisely defined behaviour is a poor match for what the hardware supports on some platform. However, it does make it a little harder to write portable programs.
Also, unlike some languages, C doesn't come supplied with a huge library of the kind that Java or C# provide. You can get very portable libraries to do just about anything, but you have to do some work to build them and get them to work together.
C does have a standard library, of course, but its scope is relatively limited in comparison with Java, C#, Python, etc etc.
-
4