Why is Java more portable than C?

click_here

Joined Sep 22, 2020
548
Is C portable? It depends on how you wrote it...

Early on it my career I learnt to write my C code in the most portable way after we had to change from one compiler to another and I had over 10,000 lines of code to go through. I had to change a *lot* of code :(

If I write a library for encryption/decryption, there is no reason why I can't use it on multiple systems: In fact I do. I also have libraries for single/double linked lists, xml parsing, and more.

It's true that you can't write a 100% portable C program with microcontrollers, because you have hardware specific things to deal with. However, you can certainly make portable libraries by following the C standards.
 

drjohsmith

Joined Dec 13, 2021
1,606
As a general statement, ( there are always exceptions )

Would it be true to say something on the lines of

Assuming you have the compilers etc,
for hardware, portability is mainly about how the code is structured ?

as an example,
I try to abstract bits that interface direct to the hardware into "units"
( I say units as the concept is code language agnostic )
and I try to have a "sensible" top level abstraction interface to the hardware code
so that I , or others, can just re write the hardware abstraction code for a new system if needed, leave the main code alone

Is it also fair to say
that for a software only person,
by which I mean one that talks to screen, keyboard in a OS environment
then Java running in a virtual machine can be run across machines without "re compiling "
as opposed to a exe file for W10, another for Linux A, another for Linux B
 

Ya’akov

Joined Jan 27, 2019
10,238
As a general statement, ( there are always exceptions )

Would it be true to say something on the lines of

Assuming you have the compilers etc,
for hardware, portability is mainly about how the code is structured ?

as an example,
I try to abstract bits that interface direct to the hardware into "units"
( I say units as the concept is code language agnostic )
and I try to have a "sensible" top level abstraction interface to the hardware code
so that I , or others, can just re write the hardware abstraction code for a new system if needed, leave the main code alone

Is it also fair to say
that for a software only person,
by which I mean one that talks to screen, keyboard in a OS environment
then Java running in a virtual machine can be run across machines without "re compiling "
as opposed to a exe file for W10, another for Linux A, another for Linux B
[tldr; Hardware abstraction layers are very helpful in making programming for multiple target environments easier but often suffer from performance deficit and programmers seeking the maximum performance will use platform specific hacks to get it in a non-portable way.

in theory Java code is more easily deployed across multiple target platforms, in practice it suffers from version dependency and may lose its edge in portability to gnu toolchain compliant C/C++ code.
]

Yes, and no.

For hardware, we have many abstraction layers. So long as a programmer follows "the rules" about how to access the hardware, code is being written for the abstraction layer and not the physical computer. In that case, any special treatment occurs in (as you said) the libraries on the target machine, the compilers, and the hardware drivers; for which the programmer is not responsible.

To the extent that it is possible to do this, code will be highly portable. The differences being handled outside the scope of writing the programs. This works to a greater of lesser degree depending on the design of the entire system, but the programmer who allows writes to the APIs will have little trouble.

However, abstraction layers are notorious for their overhead. If high performance is needed, programmers often resort to platform specific code, which can be modular and so more easily swapped in and out when needed, but it is still some non-portable code, written by the programmer and not the platform maintainer.

In terms of programs that need little interaction with the hardware, and use simple, non-performance-critical interaction with communications and HID hardware on the target, life is much simpler. But here's the rub in calling Java "more portable".

If you write a Java program that is limited by these constraints, it will almost certainly run properly on any compatible JVM. People who depend on Java in an environment with hardware diversity will know the joys of Java versioning. Java itself has a problem of portability, from version to version. It is not uncommon to have to jigger around with more than one version of Java to run critical software on one machine.

This is a practical, not theoretical problem, but it's a real problem with Java in particular. For simple programs, it's generally not a problem, but the more complex a program gets the more likely it will require a particular JVM version to operate properly and in some cases it will not run on a platform because the current JVM is incompatible and needs to be patched or updated.

On the other hand, if I am as generous as possible to C/C++, I might see it as more portable in some dimensions that might make it practically easier to maintain. If the common gnu toolchain is used, and the code it written to the same basic standards of sticking to the rules and not "programming to the metal", gnu configure, the platform specific libraries, and the linker make compiling well written code for multiple platforms pretty trivial.

It's not that maintaining the libraries, etc., is not in the aggregate a lot of work, it is, but that work is not being done by the programmer (usually) and it is distributed and so many hands make lighter work of it. Package managers allow end users to easily install software, and much of it is precompiled. When it requires architecture accommodation within a platform, it is downloaded as source, then compiled after configure does its magic.

So, theoretically Java has an edge, it should take much less time for the end user to being using a new program. In practice, though, software properly to participate in the gnu toolchain ecosystem is surprisingly portable.

It often comes down to where you end up spending your time, and who is "you" spending it.
 

ApacheKid

Joined Jan 12, 2015
1,762
Hello,
I understand that when we write a java program (the source code) we must then pass the source to another program called "interpreter" which comprises both a compiler and a JVM (java virtual machine). The job of the compiler is to convert the source code into bytecode. Byte code is NOT machine code but it is closer to assembly-like code... Bytecode is executed by the JVM which is a program that acts like an abstract/virtual hardware. The JVM does NOT convert the bytecode into machine code, correct?

Bytecode is platform independent. However, the JVM software component is platform specific: if we use Windows, we must download a Windows specific JVM, if we use a Mac a different JVM. The JMV is therefore platform dependent.

When we talk about code written in C, we say that C is not a portable language because the C compiler is platform dependent and the resulting machine code is platform dependent. More portability means "less" platform dependent. However, while the Java bytecode may be platform independent, a user still needs to have a platform dependent piece of software, the JVM, to run the bytecode. So why do we then say that Java is more portable than C?
We could write the same code in C and either compile it and share the executable with users having our same platform (OS+CPU) or directly share the C source code as long as the users have a suitable C compiler on their machine. If we wrote the same program in Java, users would still need to have a platform specific JVM. In both cases (C and Java), the users need platform specific software installed on their machine. So how is java more portable than C?

Thanks!
Many of the responses above answer your question well I think.

It is the code that get's executed too that's portable in the Java world, the bytecode, which means you have portable runtime libraries at your disposal (Maven etc in the Java world) there's no comparable thing in the general world of C.

I think the most robust example of binary portability today is in fact .Net. It is now a standard (until recently named ".Net Core") and is pretty seamlessly portable across Windows, Linux and Mac - there are platform specific libraries but its pretty hard to use these accidentally to create non portable code.

As others have said the GUI side of stuff is where that is a problem, however Microsoft are hard at work leading the initiative to get even that truly portable.

But none of this is helpful in the world of Microcontrollers! Having said that there is .Net nanoFramework which once again has started to pick up speed and has some serious Microsoft resources being thrown at it.

I dabbled in .Net Microframework some years ago and also nanoFramework too, these initiatives were stop/start and were hampered by lots of undecided design type question even though people were contributing to the projects, they both kind of just froze a few years ago.

But nanoFramework is active again, there's a lot going on and I should revisit to see what the current state of play is.

If this can be delivered (and I'm sure it can) it would be pretty good, I'm sure there would be a lower bound on the resources needed but it is being done today to target resource constrained devices, this stuff does not need any kind of host OS.
 
Top