Forgot your password?
Programming Books Media Book Reviews IT Technology

Write Portable Code 397

Posted by samzenpus
from the measure-twice-write-once dept.
Simon P. Chappell writes "Much as a certain large software company located in the North-West of the United States of America might wish otherwise, there are many different operating systems and platforms in use in the world today. Software these days needs to able to operate in a disparate environment, either by communicating with these other platforms or by running on them or, increasingly, doing both. The Information Systems industry is making good progress with the communication half of the problem (even if a lot of it seems to involve large amounts of XML), but it is still struggling with the issues inherent with writing portable code. Brian Hook's contribution to all of this is Write Portable Code , which according to it's subtitle is an introduction to developing software for multiple platforms." Read on for the rest of Simon's review.
Write Portable Code
author Brian Hook
pages 248 (14 page index)
publisher No Starch Press
rating 8/10
reviewer Simon P. Chappell
ISBN 1593270569
summary I recommend this book to anyone working with portable code.

This is a book for computer programmers who write software designed to run on multiple platforms. It's also for programmers who suspect that their software may need to run on different platforms. This brings the book onto the radar for free and open source software authors, as they seek to create software that does not trap their end users into using specific operating systems. The Structure

There is a good progression shown in the eighteen chapters of the book. The first couple of chapters introduce the reader to portability concepts and then to some of the specific portability features of ANSI C and C++ that are used throughout the rest of the book.

The middle chapters of the book, cover individual portability topics. Some of these topics are the obvious ones, like Floating Point numbers, Networking, Operating System, File System and Dynamic Libraries. Other topics are less intuitively associated with portability, but when you read the chapter, it's inclusion is both obvious and necessary. These subjects include Source Code Management, Compilers, Scalability and Data. There is more to portability than many of us might suspect.

The last two chapters look at some alternative ways of getting portability. Scripting languages are discussed and the pros and cons of each ones portability is weighed. Lastly the use of cross-platform libraries and toolkits is addressed. Quite apropos given that the book's author is also the author of a cross platform library.

As an example of the thoughtful approach taken in this book, lets' take a look at the chapter on scripting languages. It's about the shortest chapter in the book, but representative of the approach that Mr. Hook brings to his work. This chapter takes a very honest look at the portability and cross-platform aspects of using scripting languages. There are advantages and disadvantages to the use of scripting languages. The advantages include everything that is a disadvantage of low-level languages like C/C++. Scripting languages do not require you to worry about about memory allocation, bindings, System API calls or any of the other bugbears of a low-level language programmer's life. The disadvantages of scripting languages naturally include performance, given their interpreted natures, a general lack of tools, such as development environments or IDEs and their tendency to sit high above the operating system with a corresponding detachment from low-level facilities and services of that same operating system. Mr. Hook's choice of scripting languages to consider was interesting. I expected Ruby and Python; both popular and capable in their own right. The inclusion of JavaScript/ECMAScript was also not too unexpected, now that standalone versions are bubbling up and becoming available. The real surprise, albeit a pleasant one, was the inclusion of Lua; a scripting language designed for platform portability and which seems to have managed to fully mature without making a blip on most geeks radar screens.

I like that Mr. Hook has experience writing portable software. This matched with his authorship of the Portable Open Source Harness (POSH) portability library and his contributions to the Simple Audio Library (SAL) gives a great deal of credence to his writing.

This is a solid "doing" book. Mr. Hook is under no illusion that he's writing an introduction to programming. This book has a consistent purpose to take experienced programmers and fully equip them to deal with portability and it does not deviate from this in the slightest.

The layout of the book is first rate, with clear typography, comfortable spacing, clear diagrams and tables and nicely highlighted callouts. I did not notice any obvious typos or glitches in the book. While the look of a book is not the author's fault if it is below par, a well presented book can enhance the reading and learning experience.

The examples are as realistic as possible. While some of the examples to teach principles might be simpler, they are typically backed up with examples from either the POSH or SAL projects, showing real world portability coding. The level of C/C++ required to understand the examples is higher than many books that I've read. That's not to say that the code seems obfuscated, but it's code that is taking into account aspects of the real world and is, by necessity, not simple. A further positive quality of the code examples is that they're very well explained; well enough that an inexperienced programmer with determination could follow them and come to an understanding.

Appendix B contains a summary of all of the portability rules presented through the book. There are twenty rules and each is reprised with a small explanation/reminder of it's application. An example: Rule 4 - "Never read or write structures monolithically from or to memory. Always read and write structures one element at a time, so that endian, alignment, and size differences are factored out."

If you're looking for more of a fluffy "about" book, then this is not it. This is not a complaint, rather I offer it as something to consider, before you buy what you might otherwise think is a beginner's book.

I must reiterate the non-trivial C/C++ example code the book contains. This book is for serious programmers and is not afraid to role up it's sleeves and cut real code.

This is a very well written and very readable book. There are many aspects to the subject matter of portability and Mr. Hook addresses more of them than many of us had previously suspected existed and addresses them with firm authority. I recommend this book to anyone working with portable code."

You can purchase Write Portable Code from Slashdot welcomes readers' book reviews -- to see your own review here, read the book review guidelines, then visit the submission page.
This discussion has been archived. No new comments can be posted.

Write Portable Code

Comments Filter:
  • by Microlith (54737) on Wednesday November 09, 2005 @02:39PM (#13990653)
    Truly portable code is like flipping someone the bird.

    No matter what country (OS) you're working in, everyone understands it!
  • by Anonymous Coward
    Thank the ghods for the USB memory keyfob!

    moderation suggestions:
    +1 funny -1 offtop +1 informative -1 flamebait
  • Java ??? (Score:3, Funny)

    by djbckr (673156) on Wednesday November 09, 2005 @02:42PM (#13990683)
    Hey, just write whatever it is in Java. You know, "write once, run anywhere". Simple!!!
    Yes, this is a joke.
    • Re:Java ??? (Score:3, Funny)

      by OakDragon (885217)
      You can always use my model: "write anywhere, run once!"
    • by Anonymous Coward
      I know you're kidding, but unfortunately there are a lot of responses here which indicate that Java is the end-all and be-all of portable programming.

      I'm sorry folks. Such people have never done real cross-platform programming. Java simply isn't an option on MANY platforms. If all you do is x86 platforms, and perhaps some Motorola workstation-class platforms, hey, you're fine.

      But that's not the real world.

      The real world includes MIPS, ARM and other processors. What's more, the embedded world makes up most o
      • I'm sorry, but if you can't manage to track down a JVM for your platform, you need your geek card revoked. I mean, hell, there are JVM instructions built into the damn ARM processors []! What more do you want, an Angel to come down from the sky and say, "Hey you, over that way!"
      • by plumby (179557) on Wednesday November 09, 2005 @07:08PM (#13993356)
        I know you're kidding, but unfortunately there are a lot of responses here which indicate that Java is the end-all and be-all of portable programming.

        I'm sorry folks. Such people have never done real cross-platform programming. Java simply isn't an option on MANY platforms. If all you do is x86 platforms, and perhaps some Motorola workstation-class platforms, hey, you're fine.

        But that's not the real world.

        Might not be your real world, but in mine (enterprise-scale apps for a multinational financial company), we have no problem with portable Java (usually developed on Windows, mostly run in test/production on HP-UX, with the occasional Solaris and now Redhat Linux, and even a little running on our IBM mainframes).

        It's true that for some uses, such as certain embedded devices, Java is almost certainly not a sensible (or even possible) option, but in much of the industry it's a perfectly sensible choice for cross-platform development.

  • web apps (Score:3, Insightful)

    by xikzantric (929298) on Wednesday November 09, 2005 @02:43PM (#13990691)
    and this is why web applications are becoming so's much easier to make something written in PHP and distributed through the web available to everyone than to try to port something in C++ across a bunch of platforms. imho this trend towards AJAX and more web applications is a good thing and makes it easier on developers trying to deal with clients on multiple platforms. i don't want to have to deal with porting applications (although cross-browser compatibilities offer their own complications).
    • Re:web apps (Score:3, Insightful)

      AJAX and fat web apps are turning the browser into the new development "platform". The browser isn't nearly as robust a platform as, say, Java, only by virtue of the statelessness of HTTP. Not everything needs to be a web app. I know eventually some jackass is going to make an AJAX word processor/spreadsheet, but does anyone else see that this is just wrong?
      • I'm with you. I detest the fad of having absolutely everything run through the browser. I still haven't seen any web app that can compete with a similar rich client side application. The loading times are also a pain in the ass and nothing you can do with Ajax will completely eliminate that.
      • > I know eventually some jackass is going to make an AJAX word processor/spreadsheet, but does anyone else see that this is just wrong?

        wasn't it a while ago that Google wants to take over Microsoft's dominance by moving every desktop app onto AJAX, thus nullifying the significance of the OS. if a new version of AJAX can output to your speakers, i'll bet Google will create an OGG streaming AJAX player.
    • I write simulations with GUI's in C++ exclusively and I develop in both Linux and XP (depends on the customer as to the final platform, but I code on both depening on where I am). Its easy to do c++ cross-platform. The only difference is I type "make" on the Linux box and "nmake" on the Windows box :P

      hint: use standard C++ calls, don't get locked in to vendor-specific functions, use cross-platform libraries for the rest (opengl, xerces, etc.)

      • by Rei (128717) on Wednesday November 09, 2005 @03:06PM (#13990900) Homepage
        C++ also has some very nicely organized ways you can write portable code. For example, data serialization - if I care about a piece of code being portable, all of my "structures" that may need to be shared are classes with the functions "serialize" and "deserialize", and all of the member variables/structures are classes with such functions (down to the most simple members, which are just wrappers around basic types; you can even wrap vectors and maps so that arrays of any kind are dealt with automatically). Each class's serialize function simply calls the serialize function on all of its members that need to be preserved; only the most basic types actually do any IO themselves.

        The net effect is that no matter how you change your code, or even if you template it over a range of types, everything always gets written out and read back in properly without having to resort to constantly changing special case read/write functions or having to know what is in every structure and how to write it. It keeps it very simple indeed. You could have a structure nested twenty levels deep containing arrays (vectors) and associative arrays (maps), and go in and change a dozen datatypes at different levels, and not have to modify a single piece of reading/writing code.
        • While your solution works, I'll admit that the whole serialization thing is one of the nicer things about Java. Obviously there are other pitfalls with the language, but serialization is one of the things done "well" in most cases. I only wish there was something like that for C++, or the standard libraries at the least, with perhaps a class you could extend with your own class wherein you serialize your own primitives, or something.

          I dunno, rambling. But Serialization is a real PITA sometimes.
    • Web apps are also nice in that you don't have to distribute client programs, making administration a lot easier.

      Of course there are serious drawbacks to web apps. For instance, I've been demoing an opensource document management system that's web based. It seems to have many of the features that I'm looking for, but checking files in and out via a web browser is a big enough pain that I don't think that my users are going to happy with it at all. So while the developers have a product that can run on jus
    • Yes but those web apps have to run on an operating system and if the person who hosts this app wants to switch from windows to linux or from linux to the hurd (hey it'll be ready within the next ten years, no?) it would still be nice if it's portable.

      This is probably no biggy with php but that's the scripting language bit of the book about i guess. But sometimes these web apps use some pogram which is not scripted. Google has some web apps but i don't think they can switch os easily in the backend.

      Webapps a
    • Webapps are okay for some things, but are inferior and unsuitable for most. The major problem is the limitation of the interface. You can make it look pretty, and with Ajax, even make it somewhat interactive, but you can't make it very usable.

      But not every application is a front end to a backend database. I know this sounds like heresy to you database programmers, but it's true.
  • os (Score:2, Funny)

    by chris macura (899109)
    What? Are you telling me that the OS I've been developing won't run on Windows, Linux, and OS X?

    Whad` up wit` dat, fool?
    • by wpmegee (325603)
      Well, if you're a sadist and don't want a usably fast system, follow M$'s example and write large parts of the Operating System in Visual Basic, Java, or your $INTERPRETED_LANGUAGE of choice. If you don't believe, me download the Win2k source and see for yourself. Then all you have to do is write the interpeter in assembly/C/C++.

      And if you're dumb enough to do all that, chlorinate the gene pool by removing yourself from it.
  • Cross platform as long as it's Windows or *nix. How about zSeries, iSeries, HP NonStop, etc.
    • Re:Cross platform (Score:4, Insightful)

      by Just Some Guy (3352) <> on Wednesday November 09, 2005 @03:43PM (#13991240) Homepage Journal
      How 'bout 'em? Since they have basically nothing whatsoever in common with other "small" systems, I doubt there's much you can do for them besides shooting for POSIX compliance and crossing your fingers.

      Write Once Compile Anywhere will never be completely realized since various systems have incompatible design goals. No matter how portable you've made your command line application, it probably won't make a lot of sense on a Palm. That's not a limitation of your code or PalmOS, but an acknowledgment that they're different animals.

  • Portable Mac apps? (Score:4, Insightful)

    by I'm Don Giovanni (598558) on Wednesday November 09, 2005 @02:49PM (#13990740)
    How can I write portable versions of Mac OS X apps when the Cocoa API doesn't exist outside of Mac OS X (don't tell me about YellowBox or what-have-you) and the language Objective C isn't supported outside of Mac OS X (Apple is killing off Cocoa's Java support)? Oh, and the Carbon API doesn't exist outside of Mac OS X either (but at least it uses a widely supported language). You mentioned a software company in the Northwest US, but what about the one in Cupertino? Apps written to their platform are no more portable than Windows apps.

    Besides that, apps that aren't able to take advantave of the underlying platform's unique features aren't sellable. Mac users in particular want apps that take advantage of the unique features of Mac OS X (and no, they don't consider some unix app to be a real "Mac" app, and rightly so). That means Cocoa or Carbon, and neither api is supported outside of Mac OS X.
    • by Dr. Manhattan (29720) <.moc.liamg. .ta. .171rorecros.> on Wednesday November 09, 2005 @02:57PM (#13990810) Homepage
      How can I write portable versions of Mac OS X apps when the Cocoa API doesn't exist outside of Mac OS X

      Well, you factor the UI away from the engine. The guts can do things portably, perhaps with a few wrappers (I have my own personal set that abstracts threads, so I can use POSIX threads and Windows threads without having to change the guts around). The user interface can be as Maclike as you want.

      • by Sax Maniac (88550) on Wednesday November 09, 2005 @04:44PM (#13991918) Homepage Journal
        Indeed, but I'll take this one step further. The rule is any external API that you rely but don't control should be factored out similarly. It's not just UIs, though, UIs are the most common, because they change fashion very quickly.

        Let's say that you have a Windows app that relies on DirectX for some stuff, OpenGL for other stuff, some POSIX functions for yet others. Each one of those APIs represent a possibly different porting problem: move to a different platform, and one of the libraries might be missing or poorly implemented.

        So, if your code intermixes calls to all three libraries, you are going to have a hell of a time porting it over. Example: you move to IRIX and now you problably have a good GL implementation, but too bad, it's mixed up with DirectX code, and now you have to rewrite all that code, even though the GL calls would work.

        Portability is in the eye of the beholder. X code is mostly portable, but, you need an X server on the other side. So writing portable X code isn't going to help you make your native Mac UI application. Once you take the view that X is just another external API, and you wall it off appropriately, you've done you work.

        Now, you can group APIs - if you're on windows, you are pretty much assured that, say, Win32 GDI calls and DirectX are going to be there, so no need to go overboard and factor them out separately.

        The devil is choosing your abstractions. You can't over-abstract, otherwise the application will be too alient and never be completed. You almost have to have a sense of where the project will go in the future and what the most critical components are.

    • 1) Objective-C is supported wherever gcc is. Get a klew.

      2) With the GNUstep api, you can write code which targets Cocoa but is portable to other platforms. You may have to rebuild your NIBs in Gorm, however; but if you wrote a platform-agnostic back end this is a cosmetic issue.

      3) If you're using Carbon, your interests really are Mac only.
    • by WillAdams (45638)
      Try GNUstep, which is an opensource re-implementation of NeXT/Sun's OPENSTEP standard: []

      It'll allow you to deploy on Linux, Windows, and possibly even the Sharp Zaurus depending on your project.

      They even have a web page up clarifying a mention of it in Aaron Hillegass' _Cocoa Programming on Mac OS X, Second Edition_ s.html []

      It's licensed under the LGPL, so should be usable for most tasks.

      • Except that GNUstep/NeXT apps feel alien anywhere outside of NeXT. They're not so bad under OSX, but they're jarring under traditional Unix or Windows. They may look correct, but they just don't *feel* correct.
    • It's not a perfect solution (nothing is), but you might give Qt a try. I criticized the guy suggesting you try GNUstep, and my criticisms also apply to Qt. But both have one advantage: they're portable. A native Mac OSX app doesn't do Windows or Unix users any good.

      apps that aren't able to take advantave of the underlying platform's unique features aren't sellable.

      Rubbish! Integration is great, but it's hardly the end-all and be-all of software. There are more worthwhile features out there than mere nativen
  • Trolling? (Score:5, Insightful)

    by CDPatten (907182) on Wednesday November 09, 2005 @02:50PM (#13990757) Homepage
    "as a certain large software company located in the North-West of the United States of America might wish otherwise, there are many different operating systems and platforms in use in the world today. "

    If his first sentence isn't trolling I don't know what is. Why is it ok to do it against MS, but nobody else?
    You do it against MS, you make the front page, against apple you get flamed.
    • Because it's not as funny when you try it the other way:

      "Much as that nerd from Finland might wish otherwise, there are many different operating systems and platforms in use in the world today."
    • Mainly because Microsoft is the only major company that's explicitly stated a desire to control all aspects of computer. A judge even found them guilty of working toward those ends.

      Linus flat-out said that he doesn't want to own the world. I'm sure Apple would love to sell more machines, but they've positioned themselves as the low-volume, high-end solution (sort of like Mercedes or Cadillac). Microsoft, though, wants it all and has said this on many occasions.

      That is why you can justifiably say the

  • I did RTFA but haven't RTFB. I appears it is oriented toward non-UI intensive modules. Java, as others mentioned, handles the UI stuff quite well. The GNU build utilities help a lot if it's a *NIX system, but most true portability problems require more OS's.
    • "Java ... handles the UI stuff quite well"

      Who put crack in your weaties this morning?


      • Re:What About UI? (Score:3, Informative)

        by miyako (632510)
        If you want a cross-platform GUI, then I think Java/Swing is the way to go a lot of the time.
        I program mainly in Java and C++, and if you are looking just at desktop machines (which is what I work with) then it's really not a big deal either way since you are mainly looking at *nix, Windows and maybe OS X. Swing is pretty much write-once for all three platforms- though you have to do some funkyness to get mac programs to look like mac programs under OS X. Qt is available for all three platforms as well.
  • by dslauson (914147) on Wednesday November 09, 2005 @02:52PM (#13990772) Journal
    I got my first job and started digging into some code that was written for portability, it all seemed so obfuscated.

    I was like, "Why are they #defining all their data types to something else? And what's with all the crazy compiler directives?" It seemed like they were going out of their way to make the code less readable.

    Once I figured out that it was all there so that the code could be recompiled for different platforms, it all clicked together. It's really cool, and I'm pissed that I got out of college not knowing this stuff. It should be a required course, IMHO.
    • by ajs (35943) <ajs&ajs,com> on Wednesday November 09, 2005 @03:15PM (#13990977) Homepage Journal
      That's right, you heard me. Don't write portable code.

      Use portable libraries and languages; re-factor your working code to be portable; make high-level choices that support portability (e.g. don't lock yourself in to proprietary solutions), but don't write portable code.

      Why? Because premature portability, like premature optimization is a red herring that steals your attention from the only two things that will ever matter: correctness and maintainability. Write correct code. Write verifiably correct code. Write maintainable code. Do these things and you are done. Then, port it to another platform or ten and optimize the hell out of it. Don't do these things up-front, as they buy you nothing on the first pass, and doing them later will give you the chance to re-consider the structure of your system which you should do at least twice before your first release anyway.

      That said, do not snub portability unduely. If you have the choice of trivially supporting or not supporting portability-enhacing features (e.g. in your choice of a configure/build system), there's no reason not to be portable. Just don't let it set priorities for your project from day one.
      • Yeah, um, that only makes sense in certain contexts

        For example, I work for a company writing embedded software for medical equipment. For testing and QA purposes, we have to target two different architectures: VxWorks for the embedded stuff, and Windows for simulation. From the start, portability has to be a consideration, because code that doesn't port to these two platforms is completely worthless to us, and will have to be rewritten.

        I get your point, and that makes sense when writing desktop apps and p
      • Use portable libraries and languages; re-factor your working code to be portable; make high-level choices that support portability (e.g. don't lock yourself in to proprietary solutions), but don't write portable code.

        I agree completely, as long as you're targetting a platform that's completely static and not, say, in the process of switching from 32 to 64 bits. If you're not coding for PowerPC or x86, then go ahead and write all the non-portable code you want. It probably won't bite you in the butt when

    • Enjoy reading the windows.h did yea? :-)
    • Bah! (Score:3, Funny)

      Write on the bare silicon, with a microscope and an electron beam.

      Compilers are for feebs who can't read schmatics!

      Portability is for indecisive cowards!

      | Sorry |
  • by Dr. Manhattan (29720) <.moc.liamg. .ta. .171rorecros.> on Wednesday November 09, 2005 @02:53PM (#13990777) Homepage
    Best combination is one big-endian, one little-endian, and a 64-bit machine. That catches at least 85% of the portability problems right off the bat, and has the bonus of catching memory errors very quickly. Something that silently corrupts data on one platform will often cause an instant loud crash on a different one.

    "If you haven't ported your code, it isn't portable."

    Sticking to the libraries and (subsets of) languages that are really portable helps, too, like this book appears to cover, but if you just start off on a small mix of platforms, it becomes usually quite trivial to port to others. My Ostiary program runs on (at least) Linux, *BSD, OSX, Solaris, HP-UX, AIX, Tru64, IRIX, and Cygwin. I've written commercial code that runs on all of those plus Windows, NetWare, and OpenVMS, though that requires a few more #ifdefs.

    • Mod parent up (Score:4, Insightful)

      by dpbsmith (263124) on Wednesday November 09, 2005 @03:01PM (#13990856) Homepage
      Amen, brother.

      I've been involved in way too many projects where people said, "Oh, yeah, we're doing all our development on Windows but it's no big deal. We aren't going to use anything non-portable."

      Then, when the time came to port it... it was utterly intertwingled with Windows-specific cruft, half of which crept in because nobody even knew they were doing it. If they'd ever tried even once to port it, they could have caught this stuff as it happened.

      I don't mind a conscious decision to use .ini files, or CStrings, or what have you. It was all the non-portable things they did without even knowing it--and the fact that the non-portable stuff was salted and peppered evenly throughout the whole project instead of concentrated in a few well-defined modules--that got to me.

      And it didn't help that everything was compiled with permissive compiler options regarding C/C++ conformance, and a low warning level.
      • To be fair, while I strongly appreciate them (and run with werror), sometimes warnings can be problematic. As an example, I recently coded something similar to the following for a home project:

        void foo::bar()
        T var = random();
        if (sizeof(T) == 8)
        var 32;
        var |= random();
    • Best combination is one big-endian, one little-endian, and a 64-bit machine.

      And a RISC box for catching SIGBUS [] issues.

      Stuff like this -
      char * p = malloc(128);
      *(long *)(p+2) = 0;
      • And a RISC box for catching SIGBUS issues.

        Good point. In practice, I've found that developing on Linux/ia32, Solaris/SPARC, and then something 64-bit works pretty well. If you'll need to port to things like Windows or oddballs like Netware or OpenVMS (floating point isn't the same there!) it makes sense to test occasionally, but if you do the first three you'll be, like I said, about 85% of the way there already.

  • by drgroove (631550) on Wednesday November 09, 2005 @02:53PM (#13990778)
    are done w/ J2SE using SWT as the front end. Looks like a native app, runs super fast since it relies on native widgets, and portability issues are largely mitigated for me.
    • Is this what the Azureus bittorrent client uses? Not bad, but it is still a bit slower than a native app.

      • Yes, Azureus uses SWT for its GUI as does Eclipse and RSSOwl. However, from what I've found Swing has made some very strong improvements in performance over the past few years, especially with the 1.5 VM. The next VM release should also really speed up some aspects of Java GUI performance. Personally, as it stands now I would much rather write programs using Swing however that's just a personal preference. From recent experience, I think SWT and Swing are so close now in terms of performance that I thin
  • From id? (Score:3, Interesting)

    by dFaust (546790) on Wednesday November 09, 2005 @02:56PM (#13990801)
    Is this the same Brian Hook that previously worked at id software??
  • by Anonymous Coward on Wednesday November 09, 2005 @03:01PM (#13990850)
    First, C. was going to free us from non-portable code, by abstracting away the underlying assembly language. But hardware was different, and required different libraries to communicate with it. Not all the libraries were identical, and things diverged.

    Then device drivers and operating systems were going to let us abstract away the details of the underlying implementation of the hardware, letting us write portable code. But not all O/S versions are compatible; there are glibc issues under Linux, and so on.

    Then JAVA was going to be completely portable to all operating systems. But not all Java virtual machines are identical, and different version of Java came out, and things diverged.

    All of these things made life more portable, to some degree. All of them still require boostrapping a system that understands the underlying hardware and deals with it efficiently; then abstracts all that hardware specific efficiency away again.

    Portability is *hard*: in some sense, it's the enemy of efficiency. You need to abstract away all those nice hardware specifics that make the hardware work, and replace them with a theoretical construct that caters to the lowest common denominator that you're willing to support.

    What's worse, as soon as someone makes a different design decision, or an improvement, or something that isn't universally adopted all at once, you have multiple versions -- divergent standards which aren't completely compatible. It happened with UNIX; it's happening with Linux (to a lesser extent, because code can merge again after a fork), and it happened with C and Java.

    What can the developer do? Just our best; true universal portability is a Holy Grail that we'll never attain, because the day we do, someone will invent a radical new system that doesn't quite fit our abstraction model...

    • > True universal portability is a Holy Grail that
      > we'll never attain

      If you're willing to accept the limitations that go along with writing to the least common denominator, Inform comes *really* close to true universal portability -- compile once, run anywhere that has the VM, which is *almost* anywhere. You can, for instance, use the same z3 module on the PDP10, Palm and Psion handhelds, Nintendo Gameboy, Atari ST, TRS80, the BBC micro, Acorn/Archimedes/RiscOS, and a *wide* assortment of other syste
    • Then JAVA was going to be completely portable to all operating systems. But not all Java virtual machines are identical, and different version of Java came out, and things diverged.

      Yet it's still perfectly possible (and really not that hard) to write portable Java.

      At my organisation, Java development is done almost entirely on peoples' local Windows boxes, before being transfered over to the HP-UX boxes for the test/production environments. To the best of my knowledge, in the past 5 years, we'e had one sin

  • Unfortunate (Score:5, Interesting)

    by under_score (65824) <mishkin-slashdot@berteig . c om> on Wednesday November 09, 2005 @03:03PM (#13990867) Homepage
    I've written production code in C, C++, Objective-C, Lisp, Pascal, many different scripting languages, and Java. Bar none, if you want to write something portable, Java is the language to use. It has the incredibly complete and mature libraries, performance is excellent, tool support with IDE's and app servers and source repositories is fabulous, and it is designed to be cross platform! Games, huge transactional systems, office apps, and utilities are all appropriate types of applications to build on Java. I've started to do scripting on FreeBSD with Java. I'll admit, it's hard to write a useful bit of Java that is less than about 10 lines of code, particularly for text processing. But that is probably the only place it is lacking. The one other place one might consider using something else is in Dynamic Client-Side Web Apps (AJAX stuff). Other than that, I always groan when people talk about using other languages for cross-platform development.
    • It's a little immature, but groovy will provide you java cross-scripting with more script-like capabilities and syntactic sugar.
    • Re:Unfortunate (Score:2, Informative)

      by keesh (202812)
      Eh? Java is 'cross platform' only in that it forces you to use the lowest common subset of all 'supported platforms'. Plus, far fewer platforms have a working JRE than a working C or C++ compiler or Perl or Ruby interpreter.
    • Re:Unfortunate (Score:3, Informative)

      by dominator (61418)
      C and C++ are "portable assembly". All the languages that you mentioned are inherently portable and cross-platform.

      What Java has going over C and C++ is a useful large standard library framework. But heck, if you use say Qt, Mozilla's NSPR, Apache's APR, Glib, or something else as your C/C++ platform you'd have many of the same advantages that the Java library gives you.
  • by xtal (49134) on Wednesday November 09, 2005 @03:05PM (#13990885) Homepage
    If the task is well defined, a small, tightly defined app tied very closely to the target API has a better chance of performing well with fewer bugs as you can spend the portability-effort in testing.

    I abstract math and models to generic C++. I tie the rest as tightly as possible to the target API and focus on being fast and bug free. In my career so far, the only code I have ever ported for business reasons ($$) has been mathmatical algorithm related.

  • by MosesJones (55544) on Wednesday November 09, 2005 @03:06PM (#13990898) Homepage

    I write portable code, I'm writing on Windows, deploying to an AMD Solaris box and the target is SPARC. I've also done this same "magic" trick on AS/400 and OS/360...

    Now me I just use the tool designed for the job of being platform portable, rather than trying to invent new standard headers (STL anyone?) that address a fraction of the problem.

    Want to do sound on multiple platforms? Graphics? Business Process? Then use Java, its what it was designed to do. And to all those muppets who shout "its not possible"... the deploy has just finished and within 30 seconds its running on two different platforms.
  • A few, simple rules (Score:2, Informative)

    by jandersen (462034)
    1. If writing for both UNIX and Windows - and/or possibly other systems, do the development on UNIX. The reason for this is simply that if you develop on Windows, you will all the time be pushed towards using non-portable features; the development toys, I mean tools, are made that way. Also, the portable parts of the C libs were made on UNIX with that system in mind.

    2. Stick to POSIX. The POSIX standard convers almost all the functionality needed for the internals of any application.

    3. Separate the GUI from
    • Funny, I did the opposite. I was developing for an embedded Linux device and it frustrated me to have to return to the 80's for my development environment. So, I wrote a hardware abstraction layer and wrote a simple simulator for Windows. Then I used Visual Studio for all my development, debugging, etc. This worked very well and dramatically accelerated my productivity. Of course I didn't have a gui (just a simple "tui") to deal with, but the application did use multimedia and internet communications - my a
  • I think portable code is awesome. I also think as long as the world has commercial operating systems, those operating systems will do their best to differentiate from each other (otherwise, noncommercial operating systems will win). Therefore, as programmers become arbitrarily good at writing portable code, I'm afraid that commercial O/Ses will do their best to make sure that they break common portability (through extensions, unsupported standards, there are plenty of examples).

    As one example, consider

  • by pieterh (196118) on Wednesday November 09, 2005 @03:10PM (#13990929) Homepage
    My team's been writing 100% portable C code since 1991 or so. We took the same approach that Apache has done since version 2, i.e. build a distinct portability library and remove all non-portable code from the application itself.

    It's amazing anyone would actually write non-portable code except through ignorance. As a programmer, I still run code written in 1991-2 (though it's been marginalised by newer work), and we have made some quite complex products (web servers, code generators) that run on anything that has standard C libraries and BSD-style TCP/IP, including OS/2, OpenVMS, and of course all Unix and Windows boxes.

    The alternative option is to use a VM. Since we write fast system software that's not an option.

    A wise person taught me this over 20 years ago: life is too short to throw out code just because some platform changed. Portability is one of those skills that lets a normal programmer like me accumulate enough quality code over time to become a master programmer.
    • It seems pretty clear you're writing server-only code. Server/command line code is trivial to make portable compared to GUI applications.
      • The principle can be extended to GUI applications, this is what tools like Qt are for. But yes, server-side code has a more focussed set of needs - sockets, process control, threading, mutexes, database access, etc.

        For GUI code, a VM obviously makes sense since performance is not usually the key thing. By "performance" I don't mean doing a fast screen refresh, I mean getting 10k-100k messages per second through a server.

        The arguments for/against writing portable code are very old, and come down to people
  • I write code for a Windows app for a living and feel the need to point out that even just limited to Windows, our code has to be aware of the different Windows versions. The 9x family in particular comes up short compared to NT/2K/XP, not fully supporting many GDI calls (which is what my code mainly uses.)
  • by ovit (246181) <dicroce@gma i l . c om> on Wednesday November 09, 2005 @03:13PM (#13990955) Homepage

    Apache Portable Runtime.

  • ....I just burn it to a CD and take it with me anywhere! :-)
  • ...obviously needs improvement, or the reviewer wouldn't be such a horrible writer. What the hell was samzenpus smoking to let this tripe make the front page?
  • Yes, I know this book is about writing portable C/C++ code.

    I have to switch between Linux and Windows (Linux has the AVR tools, Windows supports the drivers for our Vector Network Analyzer). I've written most of my (non-avr) code in Python. I've been able to move my testing code and GUI interface code effortlessly between the two environments.

    And yes, python has been released for PalmOS. So there.

  • by agslashdot (574098) <sundararaman.kri ... m ['ail' in gap]> on Wednesday November 09, 2005 @03:45PM (#13991261)
    I had to take a mandatory graduate level course CS 533 [] Developing portable software, taught by Dr. Mooney [], who was known around school as "that portability guy".

    The class went thru umpteen strategies to write portable code & culminated in a portability project, where you wrote a "Quiz Program" in C, that ran on Solaris, Windows & the Mac with minimum code changes.
    All code changes had to be confided to the stdio.h & other header libraries. I see these days he has added Java [] to the mix.

    My own experience has been that it has very limited utility in real-life ie. corporate IT. All the jobs I held since I graduated did not require an ounce of thinking portable. They were all about writing proprietary code to be run off the web, and for some 10 years, Java was the only option until C# came along. So I practised portability by default, since that was the nature of my employment in the industry. But I can see how this might be useful for somebody doing systems level programming (assuming there are still such jobs in the IT industry in the US, of course...)

  • by QuestorTapes (663783) on Wednesday November 09, 2005 @04:17PM (#13991595)
    Note: I am a C++ programmer. I didn't read the book, just the review here. Apologies in advance if anyone takes offense.

    > The first couple of chapters introduce the reader to portability concepts
    > and then to some of the specific portability features of ANSI C and C++
    > that are used throughout the rest of the book.

    I think enough software is written in languages other than C and C++ that any serious author should put C or C++ in the title when the book is C or C++ specific.

    It's not wrong that the author or publisher chose to call the book "Write Portable Code" instead of "Write Portable Code in ANSI C". But it does make me question if the author's knowledge is limited by a single-language bias.

    > The last two chapters look at some alternative ways of getting portability.
    > Scripting languages are discussed and the pros and cons of each ones
    > portability is weighed. Lastly the use of cross-platform libraries and
    > toolkits is addressed.

    Given that scripting is limited to one chapter, wouldn't it have been better to refer the reader to other works with more detail and value, and only give a paragraph or so? Particularly since the book is not trying to be about portable code in general, but portability in ANSI C, and discusses nothing (AFAIK) about higher-level compiled languages.

    The book's about C. Why clutter it with a chapter on Ruby, Python, and JavaScript/ECMAScript and say nothing about Java, Lisp, SmallTalk, etc? Writing a chapter on scripting languages strikes me as gratuitous filler.

    And any non-trivial cross-platform C application is likely to use some sort of cross-platform toolkit. So why only a chapter?

    > An example: Rule 4 - "Never read or write structures monolithically from or
    > to memory. Always read and write structures one element at a time, so that
    > endian, alignment, and size differences are factored out."

    Writing structures one element at a time is a -minimum- required for portability. It doesn't completely address byte-order issues, variable internal data representations, or data element size issues. It just ensures that structure packing and alignment issues that might change based on compiler flags are covered. But change the compiler or platform and all these issues are still there even if you write the data elements singly. They are all unspecified or incompletely specified in ANSI C.

    It's better to design a complete data representation format, including embedded version information, or just use a higher level data store engine.

    My concern is that many of the other rules in the book might be similarly too "low-level" and incompletely specified. Rather than teaching inherently better, more portable coding techniques, they might just be teaching how to work around the low-level nature of C.
  • by jd (1658) <.imipak. .at.> on Wednesday November 09, 2005 @05:24PM (#13992327) Homepage Journal
    First, split your code into four distinct modules. These modules need to be "black box" - ie: none of them can know the internals of the others. The first module should contain the internals of your code. The stuff that actually does the hard work, but doesn't try to do any I/O of any kind. It is also the only one you absolutely need to have.

    The second module deals with all the user interface stuff and nothing else. Any event handling is done in this module and nowhere else. That way, the rest of your code doesn't need to worry about what type of execution model is being used. It'll just work as you would expect. If there is no user interface, you don't need this module.

    To make the UI truly portable is hard. No specific capability is guaranteed. eg: GUIs don't guarantee a text console, and text consoles don't guarantee a GUI. My advice would be to split the module into two sub-modules. The first sub-module handles what you want to do, but contains nothing specific on how. For example, it might be filled with commands for selecting fonts, drawing lines, etc. However, it would not contain any calls to an underlying system. It should assume some abstract, theoretical, idealized user interface.

    The second sub-module (which may be a third-party library and not something you need to program at all) would then convert these commands into actual interface calls. If you're writing this yourself, I'd suggest starting with interfaces that are already fairly portable (eg: Qt, Gtk+, Ascii Art Library) where possible. If you can't, then you'll need to write alternative versions for different types of interface. But at least it's all in one place and squished down to the routine level, not entire screens.

    The third sub-module (again, third-party if available) would do the same as above but for file I/O. Again, the upper levels should make no assumptions at all. "Anything is possible in the next half hour", as Gerry Anderson would say. The lower levels then convert the "ideal" into what the system can actually do. Here, there are at least some standards. Use them. But then write special case code for platforms that can do better. Portable need not mean sub-optimal, it merely means sub-optimal (but guaranteed to work) until tuned.

    The fourth would do the same for networking. There is absolutely no reason why an application should know if you're using sockets, MPI message passing, IPv4, IPv6, DECNet or a guy waving two flags. At the application level, data comes in and goes out. The other end should be of no consequence, and the method of getting there should matter even less. High level networking should be abstract connections, using some sort of token to identify which connection is being referred to. There needs to be a middle layer here, to turn the abstract connection into a real networking protocol. The lowest level then handles the network calls required.

    You need the three layers, because you've two levels of abstraction (the network protocol and the network hardware) and therefore you need two levels of reification to turn the abstract into something usable. As network protocols can work over multiple mechanisms, the protocols are resolved first and the mechanisms second.

    Coding styles for ALL abstract components AND the first module should emphasize portability. There should be nothing system-specific there, so you should be able to use the absolutely vanilla ANSI specification of a language (where one exists). For C, if you want to cover ancient or obscure systems as well, you should duplicate all function declarations and external declarations, using a #ifdef to distinguish between ANSI C and K&R. There are probably other languages you need to support multiple variants of, just keep the areas where you need to have compile-time or interpret-time selection kept to a minimum.

    The low-level routines are only going to work on a limited range of systems, no matter what. Therefore, anything valid for that subset is fair

I'm a Lisp variable -- bind me!