Slashdot Mirror


Porting to 64-bit Linux

An anonymous reader writes "As 64-bit architectures continue to gain popularity it is becoming more and more important to make sure that your software is ready for the shift. IBMDeveloperworks takes a look at a few of the most common pitfalls when making sure your applications are 64-bit ready. From the article: 'Major hardware vendors have recently expanded their 64-bit offerings because of the performance, value, and scalability that 64-bit platforms can provide. The constraints of 32-bit systems, particularly the 4GB virtual memory ceiling, have spurred companies to consider migrating to 64-bit platforms. Knowing how to port applications to comply with a 64-bit architecture can help you write portable and efficient code.'"

120 comments

  1. Just a recompile? by Bromskloss · · Score: 1, Informative

    Provided your code isn't written in assembly, do you really _have_ to do anything else than to recompile it? Of course, you might want to make changes to make better use of the 64 bits, but to just make it run, wouldn't this be enough?

    --
    Swedish plasma phys. PhD student; MSc EE; knows maths, programming, electronics; finance interest; seeks opportunities
    1. Re:Just a recompile? by iamdead · · Score: 1

      Usually yes, but sometimes the code is so sloppily made that it won't simply build for 64-bit architecture and even when it builds, users may suffer weird run-time crashes.

    2. Re:Just a recompile? by Anonymous Coward · · Score: 0

      Provided your code isn't written in assembly, do you really _have_ to do anything else than to recompile it?

      Uh, that's what TFA's about. Perhaps you should read it.

    3. Re:Just a recompile? by Anonymous Coward · · Score: 0


      Yes, a lot of applications are very poorly coded and assume that the world is a 32bit PC running Linux, which leads to assumtions about glibc extensions not present on other unices or about pointer/int sizes.



      Good code that doesn't need to do low level access or kernel stuff should compile out of the box on any POSIX/SUS compliant platform. Unfortunately when you look at the amount of patches the FreeBSD ports collection includes you realize this isn't the norm.

    4. Re:Just a recompile? by cnettel · · Score: 5, Informative
      Unless you assume:
      1. sizeof(int) == sizeof(void*), or
      2. sizeof(int) == 4
      If your codebase only makes the first OR the second assumption, you can tweak the compiler to like you by defines. If you also assume that sizeof(void*) == 4, you have bigger problems. Note that you can do this in rather innocent ways, like dumping a complete structure on disk, knowing that pointer values will be invalid, but just assuming that the structure will be the same size if you read it back later.

      In addition, and this is hellish, a 32-bit MOV is (generally) atomic on x86. You can rely on the high-order word and the low-order word staying together, without race conditions. The memory access semantics are different on x64 and many other platforms. This is not related to 64-bitness per se, you could see if you ported to multi-threaded 32-bit PPC as well, but it will still surface if you do the transition to AMD64/EM64T/x64. Or rather, it will result in an additional one-in-a-million crash in your source, that you'll blame on bad memory chips in the user's machine.

    5. Re:Just a recompile? by Anonymous Coward · · Score: 0

      easy to answer: look at the structures and data types used

      if they use void*/ptr or long data types, they change their size, as those are 8 byte wide now, else nothing will change at all (except register usage, as there are more now)

      not to forget the compiler optimisations for alignment, but those where already 8 byte before in standard settings (didnt look if they grew for 64bit)

    6. Re:Just a recompile? by baadger · · Score: 2, Insightful

      The answer is no, RTFA. This the exact perception that it lays to waste.

    7. Re:Just a recompile? by Keeper · · Score: 2, Insightful

      That really depends on the code. x64 changes the size of a stardard pointer, but didn't change the size of a word. In the real world (assuming we're talking about an app which was always 32bit only), once you get something to build against x64, you're about 90% done (because coders are human, and people do stupid shit sometimes).

      In my experience, most of the problems will center around using non-pointer types with pointer-types. Mostly around bounds checking, offsets into arrays, pointer arithmatic, etc. I've seen some really aweful code which actually stores pointer values in non pointer types ... bleh. That intermittently breaks in wonderfully interesting ways.

    8. Re:Just a recompile? by Anonymous Coward · · Score: 0

      Are those patches sent upstream?

    9. Re:Just a recompile? by ObsessiveMathsFreak · · Score: 2, Insightful

      Provided your code isn't written in assembly, do you really _have_ to do anything else than to recompile it?

      Do you realise how difficult it is to find a healthy goat and sacraficial knife these days?

      --
      May the Maths Be with you!
    10. Re:Just a recompile? by martinultima · · Score: 1
      “Provided your code isn't written in assembly, do you really _have_ to do anything else than to recompile it? Of course, you might want to make changes to make better use of the 64 bits, but to just make it run, wouldn't this be enough?”


      Ideally, that would be the case, but in the real world, not really. A couple weeks ago I got an AMD64 box, and since then I've been working on porting my Linux distribution over. Not exactly the hardest thing I've done, but nowhere near the easiest, either. You have to re-build all the low-level system stuff first, then re-configure all the individual apps and libraries – not all of which will compile nicely on AMD64. And a good number of the things that do work require extensive patching, which often means Googling around for stuff you may need.

      And then, of course, there's the whole issue of custom build systems – I only recently found out that there's no 64-bit version of OpenOffice.org, because their build system (if I'm not mistaken on this) creates its own build tools that it then uses to compile the office suite, and it doesn't yet have support for 64-bit code.

      A lot of the time it's just easier or else just a better idea to stick with 32-bit applications. For example, in my distribution, I've actually made the Firefox build system compile it twice, once for 64-bit and once for regular 32-bit. That way it can support Flash and other plug-ins. The only downside is that you also need a ton of messy compatibility libraries, which you often have to build on a "real" 32-bit machine or else cross-compile, which is messy and often problematic...
      --
      Creative misinterpretation is your friend.
    11. Re:Just a recompile? by Bromskloss · · Score: 1
      Do you realise how difficult it is to find a healthy goat and sacraficial knife these days?
      OK, I get your point. Well put.
      --
      Swedish plasma phys. PhD student; MSc EE; knows maths, programming, electronics; finance interest; seeks opportunities
    12. Re:Just a recompile? by HappyOscar · · Score: 1

      I used to think so too, but then qmail's CRAM-MD5 patch didn't work on my machine. Among other things, while I think Linux-AMD64 treats "int" as 32 bit, it treats "long int" as 64-bit. This causes problems if people assume "long int" means 32-bit, which a lot do. This is why for size-critical stuff, I always make it explicit, with types like u_int32_t and such.

      --
      "Your mouse has been moved. Windows 95 must be restarted for the change to take effect."
    13. Re:Just a recompile? by Anonymous Coward · · Score: 0

      sizeof(void *) != sizeof(int)

      sizeof(size_t) != sizeof(int)

      Back when Linux on Alphas was new and I was porting code to it, I ran into quite a few cases where FOSS authors were careless about these.

    14. Re:Just a recompile? by Anonymous Coward · · Score: 0
      You can't just dump structures to disk and hope to read them back on another machine because of:

      a) size of embedded pointers. But that's easy to solve, put all the pointers at the beginning or the end and only dump the rest.

      b) alignment, some architectures/ABI specify that 8 byte variables should be aligned on natural boundaries, other on 4 byte boundaries (for compatibility with 32 bit versions). If you always lay out your structures by decreasing item size, it is not a problem and it improves performance. But this is somewhat contradictory with a)

      c) byte order. ASCII (or XML for the buzzword compliant) dumping can save your ass but it is slow, especially for floating point. The best format for consistent and reasonably fast transfer of floating point values between two machines (provided they use IEEE floating point but this is the case of all machines you'll find in practice) is hexadecimal floating point (%a in printf): it is way faster since it saves the heavy binary to decimal conversion and back and represents the exact bit pattern of IEEE floating point. Actually it is even better than binary since HPPA machines have different convention for NaN (and may infinities I can't remember) than everybody else.

    15. Re:Just a recompile? by John+Miles · · Score: 1

      In addition, and this is hellish, a 32-bit MOV is (generally) atomic on x86. You can rely on the high-order word and the low-order word staying together, without race conditions. The memory access semantics are different on x64 and many other platforms. This is not related to 64-bitness per se, you could see if you ported to multi-threaded 32-bit PPC as well, but it will still surface if you do the transition to AMD64/EM64T/x64. Or rather, it will result in an additional one-in-a-million crash in your source, that you'll blame on bad memory chips in the user's machine.

      Cite? I've never heard of this, and find it pretty hard to believe, to say the least.

      --
      Dahlmann tightly grips the knife, which he may have no idea how to use, and steps out into the plain.
    16. Re:Just a recompile? by Maffy · · Score: 1

      The AMD guys certainly don't seem to be sure that AMD64 satisfies this. See this trail.

      Further, I suspect that none of the processors support atomic writes of 64-bit values that are not aligned on an 8-byte boundary. If your code has not been written to ensure that values are always on appropriate boundaries (and it's very easy to get this wrong, even if you're aware of the issue), this will probably bite you. At work, we run a lot of software on both Intel and Sparc processors. It is far from unusual to hit SIGBUS exceptions on Sparc because code was written from Intel processors and doesn't worry about writing to unaligned addresses.

      Matt

    17. Re:Just a recompile? by stderr_dk · · Score: 1

      So what you're saying is that if you have a variable, that is shared between two (or more) threads and you haven't protected it with e.g. a mutex, a condition variable or a semaphore, you could have a problem?

      Well, yeah, isn't that parallel computing 101?

      --
      alias sudo="echo make it yourself #" ; # https://pipedot.org/~stderr & http://soylentnews.org/~stderr
    18. Re:Just a recompile? by Anonymous Coward · · Score: 0

      "Provided your code isn't written in assembly, do you really _have_ to do anything else than to recompile it? Of course, you might want to make changes to make better use of the 64 bits, but to just make it run, wouldn't this be enough?"

      This is nonsense. If the code were written in assembler, it wouldn't require "porting", because it would run without modifications, although it would not use 64-bit instructions.

      So, no modification would be necessary, unless you specifically needed or wanted the processor to execute 64-bit instructions.

      And BTW, in most cases that is not required. There are very few specific cases far and between that benefit from 64-bit instructions. Even the native 64-bit RISC CPUs mostly run 32-bit code because it is faster in most cases. The UltraSPARC V9 64-bit processor is a typical example of this.

    19. Re:Just a recompile? by John+Miles · · Score: 1

      I think those are just some people confused about what the LOCK prefix is for (i.e., to force an instruction to execute atomically that otherwise would not be expected to). A lot of stuff would fail very spectacularly if simple 64-bit reads and writes weren't atomic.

      --
      Dahlmann tightly grips the knife, which he may have no idea how to use, and steps out into the plain.
  2. slashdotted by Anonymous Coward · · Score: 0

    this article is slashdotted, and I have to attend an IB information session.
    can someone please email me a copy when it comes back up? thankyou

    crispeeb@gmail.com
    I am waiting to hear from you now!

    1. Re:slashdotted by Anonymous Coward · · Score: 0
  3. Not quite by Sqwubbsy · · Score: 1, Interesting

    Well, if you RTFA you'll see that there are issues with how registers are handled on certain integer values for example.
    I'm sure it won't affect your VB app, but it could affect something written in C/C++.

    I'm just wondering if this is what is holding up an AMD64 version of Flash.

    1. Re:Not quite by Nutria · · Score: 1

      I'm sure it won't affect your VB app,

      Or your Python, Perl, Pascal, Ruby, Tcl, Java, COBOL, FORTRAN, PL/1, Prolog or Forth programs.

      I'm just wondering if this is what is holding up an AMD64 version of Flash.

      Sloppy code?

      --
      "I don't know, therefore Aliens" Wafflebox1
  4. Well written portable code is fine by this+great+guy · · Score: 1

    In theory, yes. However programmers usually do stupid mistakes, like assuming that sizeof (int) == sizeof (void *) and so they think they can cast pointers to int and the other way around, while on a typical LP64 platform (like AMD64), ints are 32 bits wide and pointers 64 bits, so the cast will not work as expected.

    All in all, nothing new here, well written portable code just need a recompilation, and everything else will need to be debugged.

    1. Re:Well written portable code is fine by BenjyD · · Score: 1
      Some of their examples do seem pretty horrible, though:
      int *ptr;
      int i;
      ptr = (int *) i;
      I'm struggling to see why anyone would do that. All I can think of is something like an API using int32 'handles', which are actually pointers internally. That's pretty ugly, though - opaque pointers would be better.
    2. Re:Well written portable code is fine by Bromskloss · · Score: 1
      assuming that sizeof (int) == sizeof (void *)
      Which reminds me of something... Isn't it time for C and its likes to let us specify explicitly how many bits we want for a variable? I would like to tell the compiler that a variable should be _exactly_ 32 bits and another one _at least_ 64 bits. It's appears strange to me that an int seems to be allowed to be, well, anything it wants to be, and I will never know. Throw in arbitrary precision floats too while we're at it. If the hardware cannot handle 523-bit floats or whatever I specified, then emulate it in software -- just like it is done when compiling for processors that cannot do floating point at all. Normally, I would just specify floats with _at least_ 15 bit precision, or something, which could be handled like a 32 bit float, or whatever the CPU happens to be capable of.
      --
      Swedish plasma phys. PhD student; MSc EE; knows maths, programming, electronics; finance interest; seeks opportunities
    3. Re:Well written portable code is fine by corvair2k1 · · Score: 1

      I doubt that will ever make it into C, because the main philosophy of C is to only provide a thin layer over the bare metal, allowing you to write portable programs that run on many architectures, but can also be well-optimized for a given architecture. People wouldn't want to have their code being simulated in software without their explicit knowledge.

      However, you could implement this in a library in C++ using compile-time templates, implying very little run-time overhead (if any) for stuff that can be computed directly in hardware.

    4. Re:Well written portable code is fine by BenjyD · · Score: 1

      Isn't that mostly acheived with types.h? int16_t, uint32_t etc.

    5. Re:Well written portable code is fine by Anonymous Coward · · Score: 1, Informative

      What you want is provided by the stdint.h header (and before that, inttypes.h), which among other things, provides types which are at least X bits, exactly X bits, or the fastest type with at least X bits. Only the at-least-X bits types are guaranteed to exist, up to the maximum word size on the machine. (After all, C is still used on machines with 24-bit and 31-bit word sizes, among others, and some that don't even use 2-complement arithmetic.)

      However, using something like "int_least32_t" directly in your code is generally frowned upon. Good standard portable programming practice is to create your own typedef of the sized types:

              typedef int_least32_t answer_t;

              answer_t hello = 42;

      Floating point is generally IEEE 754 standardized and so doesn't have any special types. Besides, you don't really care how many bits a floating point type has, just its precision and range.

      Providing software emulation for user-specified bit widths, as you suggested, is a neat idea and all, but it's outside of the scope of a language like C/C++. Even newer languages generally don't offer this. Generally, C/C++ programmers are interested in efficiency, low-level hardware access, or lowest common denominator, "stupid compiler" portability, and they can't do this if they're not using non-primitive types. If you don't care about this, then you're probably using the wrong language.

      Anyway, there are plenty of arbitrary precision libraries for people who need to work with types of arbitrary, or even unlimited width. Most modern languages (not counting C) also have such types built in now, some even promoting primitive types to and from extended range types as needed.

    6. Re:Well written portable code is fine by Anonymous Coward · · Score: 0

      Just to add to this, even using the defined width types is generally frowned upon, unless you're dumping to external structures, communicating over the network, or talking to hardware, where the representation matters. (And it's still not ideal, especially for external communication. This is better handled with a marshalling/unmarshalling library like the ones for XDR, or if the compactness and performance of binary isn't a concern, various XML libraries.)

      Instead, integer types should be treated as opaque. You should still use typedefs for almost everything, since different machines have different uses for long types, etc., and you've got types like ptrdiff_t and size_t to make life interesting, but just like floating point types, most of the time you're interested in the range of an integer type, not how many bits it has, unless you're doing bitwise operations. In the common case, portable programming dictates using the range macros (INT_MAX, INT_MIN, and friends) defined in limits.h.

      Most C programmers don't even think about issues like arithmetic overflow in their code, but if you do, this is the way to go. Using typedef for your numeric types is still a good idea in any case, though, as it easily allows you to change them later.

    7. Re:Well written portable code is fine by corvair2k1 · · Score: 1

      Most C programmers don't even think about issues like arithmetic overflow in their code

      Well, that's negligence if I've ever heard of it. I thought only Java programmers were allowed to do that. ;)
    8. Re:Well written portable code is fine by Bromskloss · · Score: 1
      People wouldn't want to have their code being simulated in software without their explicit knowledge.
      But it's already done! Even if you lower your expectations, not requiring the processor to do 153-bit floating point maths, but settling for, say, 32 bits, not all processors will be able to give that to you. Thus, if you're feeling modern and brave, using floats anyway, the compiler will have to emulate it for you. Anything less, I think, would require knowledge of the instructions present on the target CPU, and that isn't really portable.
      --
      Swedish plasma phys. PhD student; MSc EE; knows maths, programming, electronics; finance interest; seeks opportunities
    9. Re:Well written portable code is fine by Theatetus · · Score: 1
      However, you could implement this in a library in C++ using compile-time templates, implying very little run-time overhead (if any) for stuff that can be computed directly in hardware.

      Proving that those who don't use Common Lisp are doomed to reimplement it...

      --
      All's true that is mistrusted
    10. Re:Well written portable code is fine by Anonymous Coward · · Score: 0

      YAY for LISP!!!!!

      ok, thats all.

    11. Re:Well written portable code is fine by Anonymous Coward · · Score: 0

      I'm struggling to see why anyone would do that.

      Obviously, you never looked at GNU-software. GCC is full of ridiculous, unmaintainable bullshit like that, as is Firefox.

    12. Re:Well written portable code is fine by Nutria · · Score: 1

      Isn't it time for C and its likes to let us specify explicitly how many bits we want for a variable? I would like to tell the compiler that a variable should be _exactly_ 32 bits and another one _at least_ 64 bits. It's appears strange to me that an int seems to be allowed to be, well, anything it wants to be, and I will never know. Throw in arbitrary precision floats too while we're at it.

      People who have forgotten COBOL and Binary-Coded Dedimal are doomed to repeat it, poorly.

      --
      "I don't know, therefore Aliens" Wafflebox1
    13. Re:Well written portable code is fine by Bromskloss · · Score: 1
      People who have forgotten COBOL and Binary-Coded Dedimal are doomed to repeat it, poorly.
      Would you like to elaborate on that? I _do_ want arbitrary precision and it would be nice to have it built in, instead of using libraries. Is that necessarily bad?
      --
      Swedish plasma phys. PhD student; MSc EE; knows maths, programming, electronics; finance interest; seeks opportunities
    14. Re:Well written portable code is fine by drxenos · · Score: 1

      An int cannot be "anything it wants to be." It is required to be at least 16 bits. All the primative types have size guarantees. int is special, though. It is usually choosen to be the target machine's most effienct size. Plus, the latest C standard defines typedefs for particularly sized integers.

      Ada allows you do what you want. You want an integer that is always 32 bits:
      type Int32 is new Integer range -2**31 .. 2**31 - 1;
      for Int32'size use 32;

      --


      Anonymous Cowards suck.
    15. Re:Well written portable code is fine by Anonymous Coward · · Score: 0

      Proving that those who don't use Common Lisp are doomed to reimplement it...

      In a more human friendly syntax leading to a better implementation.

    16. Re:Well written portable code is fine by Nutria · · Score: 1
      Would you like to elaborate on that? I _do_ want arbitrary precision and it would be nice to have it built in, instead of using libraries. Is that necessarily bad?

      COBOL uses IBM's version of BCD. Decimal numbers are a fundamental data type in COBOL, and IIRC you can make them as big as you want with PICTURE clauses.

      --
      "I don't know, therefore Aliens" Wafflebox1
    17. Re:Well written portable code is fine by larry+bagina · · Score: 1
      From an early 1990s version of the GNU Coding Standards:

      Even GNU systems will differ because of differences among CPU types--for example, difference in byte ordering and alignment requirements. It is absolutely essential to handle these differences. However, don't make any effort to cater to the possibility that an int or a pointer will be other than 32 bits. We don't support 16-bit machines in GNU.

      A lot of gnu (and unix) code assumed 32 bit ints, 32 bit pointers. Could have been worse... a lot of early macintosh code used 24 bit pointers with the high 8 bits being used for flags and such... going 32-bit clean was painful.

      --
      Do you even lift?

      These aren't the 'roids you're looking for.

  5. no by sentientbrendan · · Score: 5, Insightful

    Generally architecture changes, compiler version changes, break code on large projects. Over a million lines of code, any tiny little difference in the platform that the original developers didn't think to account for will come up *somewhere*. A good example of this is if you are dumping data structures to disk or network and write a size_t variable. Suddenly, you can no longer communicate between 32 bit and 64 bit versions of your software.

    As a general rule, "just a recompile" *never happens* for any architecture and compiler change on a project above a certain size. Compiler writers break compatibility with some little ol' thing they don't think anyone is using, but which everyone is actually using in *every* version, fail to implement uncommon or difficult language features, add non standard features that other compilers don't support. Then application developers do things like not swapping to network byte order and using architecture dependent data types (size_t as in the example). Between different unices, header file contents will change.

    The fixes are often not that hard (usually trivial) to do between say versions of the same compiler, or endian switches... but they are still there and annoy the hell out off people trying to compile old open source software on a new platform, like say macosx was a few years ago and x86 64 is now. There's always growing pains.

    1. Re:no by jgrahn · · Score: 1
      Generally architecture changes, compiler version changes, break code on large projects. Over a million lines of code, any tiny little difference in the platform that the original developers didn't think to account for will come up *somewhere*. A good example of this is if you are dumping data structures to disk or network and write a size_t variable. Suddenly, you can no longer communicate between 32 bit and 64 bit versions of your software.

      In general, I agree. But the example is not a good one. Dumping data structures to disk (or network) should be a sacking offense. I mean, this was well known to be a bad idea back in the 1970s!

    2. Re:no by sentientbrendan · · Score: 1

      Not really. It's stupid to dump the padding to disk, and it is stupid to not put things in network byte order, but not everything should be in plaintext... that's a tremendous waste of space and makes random file IO impossible in many cases since records aren't of uniform size.

  6. 64bit ain't all it's cracked up to be.. by way2trivial · · Score: 2, Funny

    I have windows XP 64bit edition, and let me tell you- that 128GB ram limit really pulls me down..

    --
    every day http://en.wikipedia.org/wiki/Special:Random
    1. Re:64bit ain't all it's cracked up to be.. by Anonymous Coward · · Score: 0

      Boy, I wish. I have 4GB in this rig, but only 2.75 is reported by Windows.

    2. Re:64bit ain't all it's cracked up to be.. by JollyFinn · · Score: 1

      There is big virus taking rest of the ram. Please back up your data and format your hard-drive and then install operating system there. After that copy the data from backups to /home/acoward/Desktop/OldFiles/ .

      Then the problem is fixed.

      --
      Emacs is good operating system, but it has one flaw: Its text editor could be better.
    3. Re:64bit ain't all it's cracked up to be.. by Anonymous Coward · · Score: 0

      "finish" only has 1 "n".

    4. Re:64bit ain't all it's cracked up to be.. by JollyFinn · · Score: 1
      --
      Emacs is good operating system, but it has one flaw: Its text editor could be better.
    5. Re:64bit ain't all it's cracked up to be.. by Rich0 · · Score: 1

      Is it really that low?

      In theory 64bit should be good for 17 179 869 184 GB. Granted, on AMD64 the process can only address 1 TB of RAM, and I think 256TB of virtual memory. However, that is a result of chip design and not arch, per se - so that can be raised without breaking compatibility at the software level.

      I believe linux supports the full range, or close to it.

    6. Re:64bit ain't all it's cracked up to be.. by Hal_Porter · · Score: 2, Informative

      It's because of the pagetables. AMD added another level to take the page tables to a 52bit physical address space. The page table entries are compatible with PAE, which most OS's already support. x86 is 3 level, x86-64 is 4 level.

      There's space in the page table entries to handle 64 bits, but adding extra levels to the translation probably has a performance impact. There's still debate about the best way to do 64 bit address translation, and 52 bits is plenty for now. And when they change, it will only affect the bits of the OS that handle paging, user application and even device drives will always see a flat 64 bit virtual address space.

      Like all of x86-64, it's a designed for a subtle mix of good performance in the short term and a painless upgrade path for current OS kernels, without really compromising anything in the long term.

      --
      echo -e 'global _start\n _start:\n mov eax, 2\n int 80h\n jmp _start' > a.asm; nasm a.asm -f elf; ld a.o -o a;
  7. Ohh, I know this one! by Anonymous Coward · · Score: 0

    Write it in Java, and it will run on 32 and 64 bit Linux, as well as Solaris and other Unixes, Windows, Mac. And you won't have to change a line of code.

    1. Re:Ohh, I know this one! by wolf369T · · Score: 0, Flamebait

      Oh, right, if you don't want a fast application. Here's a newsflash: Java is slow.

    2. Re:Ohh, I know this one! by Anonymous Coward · · Score: 0

      Oh, right, if you don't want a fast application. Here's a newsflash: Java is slow.

      No way!!!! Java programs are hellish fast because they're small because they're in bytecode!!! Without the slow libraries!!!

      My pretty booth babe girlfriend that works for SUN as a hooker on exhibitions told me that!!!

    3. Re:Ohh, I know this one! by Anonymous Coward · · Score: 0

      Not only that, but Java apps frequently start up faster than the same app programmed in any other language!

  8. Sheesh... by Anonymous Coward · · Score: 0

    Knowing how to port applications to comply with a 64-bit architecture can help you write portable and efficient code.

    Ignoring 64Bit helps a lot to write portable code. For 99.999% of all Apps out there 64Bit is irrelevant, anyways.

    Slashdot should rather stick to Buzzword-overload-articles, FUD and linking-to-manual-pages-of-linux-commands-for-08/1 5-users than giving developers proposals how to do things.

    There... 2 minutes of my precious time... gone for nothing!

    1. Re:Sheesh... by eloki · · Score: 3, Insightful

      Ignoring 64Bit helps a lot to write portable code. For 99.999% of all Apps out there 64Bit is irrelevant, anyways.

      I suspect what you're saying is that there is no particular need for 64-bit in most apps, which I agree with. But the point here is that the program should work correctly, which means code that makes assumptions like pointers and ints being the same size needs to be fixed. The point is that amd64 is making 64-bit platforms relevant to more users, not that everyone thinks most apps will be gee-whiz faster as a result.

      As a side note, some programs may realise minor performance gains on amd64 from having more general purpose registers available. This is, of course, technically nothing to do with it being 64-bit but does mean that there is a potential benefit even if you never need more than 4GB of addressable memory.

  9. Most of the time it's easy. by PhrostyMcByte · · Score: 4, Informative

    If you don't make assumptions about pointer sizes in your code, always use size_t in the appropriate places, etc, it is generally just a quick recompile for x64. I find a lot of open source code (I'm sure this isn't exclusive to open source, but, well, I can't see closed source!) spits out hundreds to thousands of warnings about assigning the return of strlen() to an int and other similar and usually harmless things, but most of the time it Just Works (tm).

    The only area I've ran into things being significantly harder is writing clean lock-free algorithms due to the lack of a CMPXCHG16B instruction in the original spec - only EMT64 and very recent AMD64 models have it. There are a couple ways to hack around this limitation but they aren't very pretty.

    1. Re:Most of the time it's easy. by Entrope · · Score: 1

      The hard part -- at least for people without a decade of intensive C background -- is knowing the "appropriate places" for size_t, ssize_t, socklen_t, and all those other fun types that are used only sometimes or in some places or on some platforms. System libraries are getting better about consistency and compatibility, and compilers are getting better about type conversion warnings, but source code that wants to run on different OSes released before 2001 ends up growing a maze of twisty little #ifdefs, all alike (but sometimes all different). If you only care about platforms from 2004 and later, you can get away with a small thicket of fairly straightforward little #ifdefs.

    2. Re:Most of the time it's easy. by runderwo · · Score: 1

      Using GNU autoconf can actually help here. In this case, it would transform #ifdef BSD, #ifdef QNX, etc etc into #if HAVE_FEATURE_FOO, cleaning up the code tremendously.

  10. Chicken-egg problem with libraries by MobyDisk · · Score: 1

    I tried compiling an application for 64-bit, and the problem I found is that many libraries weren't available in 64-bit versions. I don't mind compiling something for 64-bit, but I do mind compiling the application and a few libraries, and the libraries they depend on, recursively ad nauseum.

    Finally, when I did get it working, the maintainer didn't have a 64-bit OS so they weren't interested in hosting the RPM I built. It seems like until enough people have 64-bit systems, nobody really cares about it.

    1. Re:Chicken-egg problem with libraries by arivanov · · Score: 1

      Yep. I will second that.

      I had very similar experience when working on 64bit Linux 6 years ago in the days of Debian on alpha. I ended up lifting many libraries out of the NetBSD tree and rebuilding them for Debian because they were the only project at the time which was meticulously cleaned up to be both endian-clean and int-size-clean.

      After getting some things working I could not get the packages and patches back because people could not verify them.

      --
      Baker's Law: Misery no longer loves company. Nowadays it insists on it
      http://www.sigsegv.cx/
  11. Been there, done that by ChaoticCoyote · · Score: 2, Informative

    I've been running a 100% 64-bit dual Opteron rig for almost two years, under Gentoo. No emulation libraries, no multilib, just 64-bit code. Other than Open Office, I've had almost no trouble at all.

    BTW, "64-bits" don't make programs run faster (in general) — code compiled for AMD64/EMT64 runs faster than its 32-bit counterpart (for the most part) because of the extra general-purpose registers in the AMD 64-bit design.

    1. Re:Been there, done that by js290 · · Score: 1

      Boring... been running 64-bit linux on my Alpha since 1998.

      --
      "Tempers are wearing thin. Let's just hope some robot doesn't kill everybody." --Bender
  12. Just use a modern language by Anonymous Coward · · Score: 0

    Really...just use Java or C#/Mono and the only thing you have to do is change the SDK/JDK and re-test.

    Unless you are doing low-level system-level coding in C or C++, these two languages are perfect for creating any regular end-user app, both server side and client side.

    Worrying about 32-bit or 64-bit is so last century. You'll be worrying about year 2000 next.

    1. Re:Just use a modern language by wolverine1999 · · Score: 1
    2. Re:Just use a modern language by Decaff · · Score: 1

      Really...just use Java or C#/Mono and the only thing you have to do is change the SDK/JDK and re-test.

      Indeed. Having been through the horrors of 16-bit to 32-bit transition on Windows in the early 90s, it is great to be developing in Java, knowing that I don't have to care about such matters again. I let the JVM translate my bytecodes to high-performance machine code on whatever platform I am on, no matter what the word length.

    3. Re:Just use a modern language by Anonymous Coward · · Score: 0

      Actually if you are coding something which processes bitstrings for example, you will have the problem whichever language you're using.
      So what you said isn't really correct in all situations. Look at your code.

    4. Re:Just use a modern language by wolverine1999 · · Score: 1

      Here's a guide to porting to a 64 bit Java environment.
      http://www-128.ibm.com/developerworks/java/jdk/64b itporting/

      Many Java applications are not written 100% in the Java language. Those apps will need some porting effort. The document also mentions considerations such as the usage of JNI by the native libraries on a 64 bit system.

    5. Re:Just use a modern language by Anonymous Coward · · Score: 0

      I can say the same thing about C:

      "I let the C compiler translate my source into high-performance machine code on whatever platform I am on, no matter what the word length".

      And? What does Java or C# have to do w/ it? If your C code made or makes invalid assumptions, then it's a bug in the code. Well written C code works on any conforming platform. In fact, the C language specification posits a "virtual machine" just like Java and C# do. A compiler is free to generate bytecode for a software virtual machine on the platform. Similarly, GCJ can compile Java directly to machine code. The only difference is that the C "virtual machine" has a far looser specification than a JVM since it doesn't take for granted a 32-bit x86 or SPARC environment, nor even a process model. The JVM spec doesn't fit as neatly into a 16-bit or 64-bit environment, whereas C is just at home on an 8-bit microcontroller or a 128-bit vector machine.

      A language's power comes in how well it suits a particular task. The fact that an int on Java
      is guaranteed to be 31-bits + a sign bit is the least attrative benefit of the language, and arguably not a benefit at all (it doesn't offer me anything whatsoever, since I fortunately never internalized such assumptions as a programmer). The only meaningful comparison in this context is SUSv3 (Standard Unix Specification) versus J2EE. Now that's an interesting comparison. J2EE might have a standard XML parser, but C99+SUSv3 is a far more powerful environment for _writing_ parsers than J2EE.

    6. Re:Just use a modern language by Decaff · · Score: 1

      And? What does Java or C# have to do w/ it? If your C code made or makes invalid assumptions, then it's a bug in the code.

      You are missing the point here. I don't want to have to recompile all my stuff to suit these different machines. With Java, if a machine is running a J2SE 1.5 VM, it will run my single binary, no matter what the bit size of the target machine.

      Maintaining a source repository and having to rebuild it for a range of different target architectures (and support it on those architectures) is something I gladly gave up years ago. I target J2SE 1.5. WORA is a reality which I use on a daily basis.

      A language's power comes in how well it suits a particular task.

      Not necessarily. We are talking about the VM implementation, not just the language.

      The fact that an int on Java
      is guaranteed to be 31-bits + a sign bit is the least attrative benefit of the language, and arguably not a benefit at all (it doesn't offer me anything whatsoever, since I fortunately never internalized such assumptions as a programmer).


      It has huge benefits. It means that, for example, you can serialise information in Java and guarantee that you can restore that information on any platform. It allows for, for example, fast binary messaging between different JVMs on different platforms, so that you can cluster your application on a network of machines that not only differ in operating systems, but also on word size, and you can hot-deploy new code as binary over such a network.

      The only difference is that the C "virtual machine" has a far looser specification than a JVM since it doesn't take for granted a 32-bit x86 or SPARC environment, nor even a process model.

      Neither does the JVM - it makes no assumptions of the bit length of the host machine, or the environment. It has some assumptions - that a 32-bit integer can be handled atomically, for example, but that is it.

      The JVM spec doesn't fit as neatly into a 16-bit or 64-bit environment, whereas C is just at home on an 8-bit microcontroller or a 128-bit vector machine.

      I think you should take a look at where JVMs are installed. They have been fitting neatly and very efficiently into machines with a wide range of bit lengths for years - especially 64-bit. One of the great advantages of Java is that you can distribute your binary code to such machines, as described above.

    7. Re:Just use a modern language by Decaff · · Score: 1

      Actually if you are coding something which processes bitstrings for example, you will have the problem whichever language you're using.

      All the Java BitString libraries I have used have been platform independent; which makes sense, as a Java program has no indication of the word size of the underlying platform.

      So what you said isn't really correct in all situations. Look at your code.

      Eh? I look at my code all the time!

    8. Re:Just use a modern language by Anonymous Coward · · Score: 0

      Indeed. Having been through the horrors of 16-bit to 32-bit transition on Windows in the early 90s, it is great to be developing in Java, knowing that I don't have to care about such matters again. I let the JVM translate my bytecodes to high-performance machine code on whatever platform I am on, no matter what the word length.

      There's a reason for that. All Java datatypes have standard-defined sizes.

  13. Java progs are portable, but Java is not by Anonymous Coward · · Score: 0

    Write it in Java, and it will run on 32 and 64 bit ...

    That statement hides the real truth about Java, and the real problems.

    Sure enough, a successfully compiled Java program will run on pretty much any working Java system. Unfortunately, the Java system itself is extremely non-portable, and is a bitch to get working properly. And I've tried all the major Java implementations.

    I have well over a dozen machines, and all but two are different to each other and run different operating systems or different system releases. Pretty much all FOSS languages work on every box, with one major exception: Java. It's working successfully on just three of them, and that's not for want of trying. I've sweated blood over the years trying to get Java working.

    I'm not sure exactly what the problem is with Java, but no other common languages suffer from it --- they all work pretty much out of the box. In comparison, the Java system is hopelessly non-portable. And talking about the high portability of the bytecode isn't very helpful to people when the hosting Java implementation doesn't work on a particular system.

    My guess is that there are so many modern systems on which standard Java installs work just fine that the developers just couldn't care less about truly increasing portability so that it also installs on systems outside of the high volume mainstream.

    So, the "write once, run anywhere" of Java mythology needs changing to "write once, run only where Java happens to work". It's a pretty bad situation.

  14. Specifying bit lengths by FuzzyDaddy · · Score: 1

    My latest C project is an embedded avr system, where this is of course very important.  The solution has been to make a header file with a bunch of typedefs in it like:

    typedef unsigned char uint8;
    typedef unsigned short uint16;

    And so forth.  Then I exclusively use the new types.  If I need to compile to another platform, I just need to change the portable.h file.

    You can even go one further with:

    #if sizeof(unsigned char) == 1
    typedef unsigned char uint8;
    #else
    #error "No uint8 type available"
    #endif

    That way the compiler will warn you if there's a problem when you switch platforms.

    (This solution was not mine, but another developer's.)

    --
    It's not wasting time, I'm educating myself.
    1. Re:Specifying bit lengths by FuzzyDaddy · · Score: 1

      hmm, it seems

      #if sizeof(uint8)!=1

      is not valid syntax.  Well, I'm sure there's a way to do it properly.  Anyone?

      --
      It's not wasting time, I'm educating myself.
    2. Re:Specifying bit lengths by Pretor · · Score: 1

      As another post noted use int8_t, uint8_t, int16_t, uint16_t and etc. These are defined by ANSI C99 so that you will already find them when using GCC, Visual Studio and any other modern compiler.

    3. Re:Specifying bit lengths by FuzzyDaddy · · Score: 1

      Good to know. However, these don't seem to be support by avr-gcc (although the vi syntax coloring likes them just fine!).

      --
      It's not wasting time, I'm educating myself.
    4. Re:Specifying bit lengths by Haeleth · · Score: 1

      #if sizeof(unsigned char) == 1
      typedef unsigned char uint8;
      #else
      #error "No uint8 type available"
      #endif
      That way the compiler will warn you if there's a problem when you switch platforms.


      Um, no, actually it won't, because the sizeof operator returns the size of the type in chars. That is to say, sizeof(char) is 1 by definition, regardless of the number of bits in a char.

    5. Re:Specifying bit lengths by jgrahn · · Score: 1
      My latest C project is an embedded avr system, where this is of course very important. The solution has been to make a header file with a bunch of typedefs in it like:
      typedef unsigned char uint8; typedef unsigned short uint16;
      And so forth. Then I exclusively use the new types. If I need to compile to another platform, I just need to change the portable.h file.

      Two comments:

      Get yourself a compiler/stdlib with implements the official C99 known size types: uint8_t, uint16_t and so on. Or have fun when you find you have to integrate your software with someone elses, which uses u8, UBYTE, UCHAR, u_int8 or one of the gazillion non-standard naming schemes I've seen for the same thing.

      IMHO, you should use uint16_t and friends rarely, when you really need to for memory usage reasons, or possibly try to enforce some special memory layout on structs. It creates a lot of silent type conversions, which might have hard-to-detect bugs. It forces type conversions whenever you interface to the standard library or other people's APIs. Look at the Linux kernel - extremely portable even though almost all scalar variables are plain char, int or long.

    6. Re:Specifying bit lengths by Breakfast+Pants · · Score: 1

      make sure you include types.h

      --

      --

      WHO ATE MY BREAKFAST PANTS?
    7. Re:Specifying bit lengths by stuuf · · Score: 1

      #if sizeof(uint8) == 1
      #else
      /* sizeof(uint8) != 1 */
      #endif

      maybe... i'm not sure if the problem is that the preprocessor only understands == and not !=, or if it's something different

      --

      Everyone is born right-handed; only the greatest overcome it

    8. Re:Specifying bit lengths by FuzzyDaddy · · Score: 1
      Found it, it's inttypes.h (which is included by stdio.h) for the avr-gcc compiler.

      Cool! Thanks!

      --
      It's not wasting time, I'm educating myself.
    9. Re:Specifying bit lengths by drxenos · · Score: 1

      1) The preprocessor has not concept of "sizeof" 2) sizeof(unsigned char)is always 1 by definition 3) The latest ISO C standard already provides these types

      --


      Anonymous Cowards suck.
    10. Re:Specifying bit lengths by larry+bagina · · Score: 2, Informative

      it could be the fact that the preprocessor doesn't understand sizeof()

      --
      Do you even lift?

      These aren't the 'roids you're looking for.

  15. An example... by Anonymous Coward · · Score: 0

    The last parameter of pthread_create() is a void pointer to pass data to the new thread.

    If all you are passing is an integer value then casting it to a (void *) is the quickest method. The alternative is to malloc() some space, copy the value, pass the pointer, and make sure you free() the memory in the thread(which you should probably do at the start of thread by copying the value locally before free()'ing the memory.)

  16. Use stdint.h! by Chemisor · · Score: 5, Informative

    The article doesn't appear to mention this, but there is a C99 standard header stdint.h, which defines fixed width types. I haven't seen any OSS project use it, for some reason, but it has all the types you need for portable development; int32_t, uint64_t, constant wrappers like UINT64_C, and, of course, limit constants for all of the fixed-size types. Using these is much better than all those size-based #ifdef'ed typedefs I see people use all over their code.

    1. Re:Use stdint.h! by TCM · · Score: 1

      The article doesn't appear to mention this, but there is a C99 standard header stdint.h, which defines fixed width types. I haven't seen any OSS project use it, for some reason, but it has all the types you need for portable development; int32_t, uint64_t, constant wrappers like UINT64_C, and, of course, limit constants for all of the fixed-size types. Using these is much better than all those size-based #ifdef'ed typedefs I see people use all over their code.

      Umm, try NetBSD maybe? It's the most portable system there is. They don't port it to dozens of archs to be cool. It helps write cleaner code if you have all kinds of mixes of big-endian, little-endian, 32bit, 64bit. Each arch compiles from the same source without many warnings, if any at all.

      --
      Of course it runs NetBSD. BTC: 1NT7QvbetmANwaMzhpVL6
    2. Re:Use stdint.h! by runderwo · · Score: 1
      Linux runs on every combination of big/little endian and 32/64-bit systems, so I fail to see your point about NetBSD being unique in that regard.

      32-big: SPARC
      64-big: Alpha
      32-little: IA-32
      64-little: EM64T

  17. More subtleties can arise ... by AK76 · · Score: 5, Informative

    I did a lot of 64-bit cleaning up for the PHP project, and I can tell you that there are more subtle issues that may arise when porting from 32-bit to 64-bit.

    One example:
    on a 32-bit Intel machine, a double is precise enough to distinguish LONG_MAX (the highest representable long) from LONG_MAX+1 (a number that doesn't fit in a long anymore). So for instance, to determine whether a long multiplication has overflowed, you could repeat the same multiplication using doubles and compare the result to (double)LONG_MAX.
    In contrast, on a 64-bit platform LONG_MAX and LONG_MAX+1 are mapped to the same double representation, so there's no way to do the comparison anymore.
    As this example involves static casts, it is something the compiler will usually not warn you about.

    Another thing to be careful about is passing pointers to variadic functions (eg. sscanf), because usually the compiler doesn't know the expected types, as they are buried in the format string, not in the function prototype.

    1. Re:More subtleties can arise ... by Anonymous Coward · · Score: 1, Informative

      One example:
      on a 32-bit Intel machine, a double is precise enough to distinguish LONG_MAX (the highest representable long) from LONG_MAX+1 (a number that doesn't fit in a long anymore). So for instance, to determine whether a long multiplication has overflowed, you could repeat the same multiplication using doubles and compare the result to (double)LONG_MAX.


      That seems like a terrible way to do it... couldn't you just find the highest set bit position in the multiplicands and add?

      Or better yet, IIRC when you do a 32-bit multiply on x86 you get a 64-bit result. You might have to delve into assembly, but you can directly check for overflow.

    2. Re:More subtleties can arise ... by Anonymous Coward · · Score: 0

      Yeah, "subtleties" arise if you rely on stupid hacks instead of writing clean code, dumbass.

      Gosh, where have all the software engineers gone? The programming landscape seems to be overrun by incompetent nutjobs.

    3. Re:More subtleties can arise ... by AK76 · · Score: 2, Insightful

      First of all, this dumbass incompetent nutjob didn't write this code in the first place. It's a real world example of code I happen to have fixed because it turned out not to work on 64-bit.

      However, while it is indeed a hack, I would like to challenge you to suggest a better version that:
      a) is as portable (so no assembly for checking overflow flags that for instance Alpha doesn't have)
      b) uses only 1 multiplication and a comparison in case of overflow, and 2 multiplications otherwise.

      The point is, from a pragmatic point of view, this is a very valid solution that has always worked and produced 100% correct results until 64-bit CPUs came about.

    4. Re:More subtleties can arise ... by DimGeo · · Score: 1

      Or you can just use tye type long long.

    5. Re:More subtleties can arise ... by drxenos · · Score: 1

      Different language, but I wrote a C++ class that would range check it's value. The class uses templates to completely remove unnecessary checks at compile time. For example, assume that type R is an unsigned integer with a range of [0,100]. In the following code snippet (where x, y, and z are all of type R), the compiler will remove all but two checks (divide by zero on the division, and the upper bound when assigning the result to r.

      const R a = 5, b = 7, c = 1;
      R r = ((x + a) * (y + b)) / (z - c);

      None of the other checks are necessary because the intermediate results cannot possibly overflow the integral type used to hold them. Tests have shown that the static analysis done can decrease execution times (over code that checks every operation) by a factor of 10 or more (of course it all depends on the actual expressions).

      --


      Anonymous Cowards suck.
    6. Re:More subtleties can arise ... by Anonymous Coward · · Score: 0

      That is was and will always be beacuse PHP is a piece of shit. Can't have the free version getting too good or Zend won't make money.

  18. very wrong by r00t · · Score: 1

    On all Linux systems:

    sizeof(int)==4

    the "long" and "void*" data types may be atomically written, 64-bit or not

    Also:

    sizeof(long)==sizeof(void*)

    sizeof(long long)==8

    This is quite standard for 32-bit and 64-bit systems. The only major OS to
    violate this is Win64, which kept a 32-bit long and thus can't safely cast
    a void* to long and back again. Linux, BSD, Solaris, MacOS 9, Win32, OS/2,
    VMS, VxWorks... they all work as Linux does. (screw Win64)

  19. /lib was botched, so yes you must port libraries by r00t · · Score: 1

    When Linux was ported to the Alpha and Itanium, libraries went in /lib. Emulation libraries go somewhere under /usr, like /usr/lib/i386-linux-elf/lib or maybe /emu/i386-linux-elf/lib. Any app being natively compiled didn't need to care about this cruft.

    Then AMD told SuSE to make x86-64 run all i386 binaries perfectly, including installers that would expect to use the /lib directory. Not that we want old cruddy i386 binaries!

    So now we're supposed to use /lib64. It is so lame. It causes all sorts of trouble porting things to 64-bit, just so we dont need to do "mv /lib/libfoo.* /usr/lib/i386-linux-elf/lib/" for the occasional i386 binary.

    A few years from now, nobody will even install 32-bit crud. We'll have a /lib directory without libraries, and the "/lib64" wart lasting until the end of time.

  20. Re:/lib was botched, so yes you must port librarie by dastrike · · Score: 2, Informative
    We'll have a /lib directory without libraries, and the "/lib64" wart lasting until the end of time

    Nah. That's a bit pessimistic outlook. Already today /lib64 is a mere symlink to /lib on current distributions. The symlink may have to be kept around of for a while though until the early nomenclature oopses have been effectively phased out.

    $ uname -m
    x86_64
    $ ls -ld /lib*
    drwxr-xr-x 17 root root 4544 2006-03-26 14:52 /lib
    drwxr-xr-x 2 root root 2120 2006-04-02 13:59 /lib32
    lrwxrwxrwx 1 root root 3 2006-02-28 03:09 /lib64 -> lib
    --
    while true; do eject; eject -t; done
  21. Practice What You Preach by Stephen+Samuel · · Score: 1
    The silly thing is that his big-endian/little-endian program would break on a 64 bit bigendian system which would return '0', and not 0x12 or 0x78. You can use -2 and check for *(unsigned char *)i == 0xff or 0xfe .. but, in that case.

    Going off on a tangent:
    I have no idea what a 36 bit signed-magnitude integer mainfraim (( Yeah, they really existed -- CDC made them )) would return for *(unsigned char *) (int)-2. It would probably be 0x80 or 0x40 -- but it might be 0x800 (CDC used 6 bit characters, and case shifting was done by using a second 'escape' character -- rather like unicode, so a 'char' might be either a 6 bit or a 12 bit unit -- or an 8 bit unit just to keep from choking every C program under the Sun)

    --
    Free Software: Like love, it grows best when given away.
    1. Re:Practice What You Preach by Anonymous Coward · · Score: 0

      It would be reasonably accurate to say that I have no idea what the fuck you are talking about.

  22. Written For Macromedia by jack_csk · · Score: 1

    I am wondering if this 64-bit porting article is written specifically for Macromedia.

  23. 64 bit porting is more of a compiler problem by tlambert · · Score: 1

    64 bit porting is more of a compiler problem.

    In particular, the GNU toolchain has a very poor ability to complain about long/int coercion. It also doesn't have a 64 bit pointer type for use in 32 bit code - so any 32 bit code you need to talk to from 64 bit ends up handing around a long long, and since this is just an integer type, there's no problem with assigning it to another integer type, and potentially losing resolution (and bits off the pointer, should it be converted/passed back).

    Minimally, the tools need to have a flag that complains about integer assignment between 32 and 64 bit values. Ideally, they would also include a "long void *" or some other pointer type whose type coercion would result in a warning being generated, unless the coercion was done with explicit casts.

    The assignment warning has been asked for many times in the past by people trying to move ILP32 code into an LP64 environment, and of course, the tools people have objected to the idea because it would cause additional warnings that they'd have to explain how to coeerce around.

    The objection to adding a 64 bit pointer type for use in 32 bit code, I can somewhat sympatize with - but they added "long long" well before it was standardized, even when it was obvious that the most correct thing to call it would be a single token like "quad" so it could be defined in and out, without having to typedef or replace explicit types. So the argument against it is very weak.

    They've also messed up and refused to correct things that are obvious breakage (e.g. "typedef char *caddr_t; const caddr_t foo" results in a "char const *foo", rather than a "const char *foo", and "caddr_t const fee" results in a a "char const *fee" instead of a "char * const fee" -- meaning it's impossible to use typedef'ed values in function declarations using const in some circumstances).

    Speaking of all of which -- when are we going to get a flag so that "typedef char *caddr_t; extern void fum(char *); caddr_t foo; ... fum(foo); results in a type warning?!?

    The vast majority of problems that arise when porting between ILP32 and LP64 are things which would be trapped by the addition of a few warnings to the compiler - but without those warnings, it becomes a Herculean task requiring a level of detail work and precision very difficult to keep up over the amount of time necessary for a large project porting effort. It's no wonder this is becoming a visibility issue, as 64 bit hardware becomes more prevalent, and people decide they want to run their code over there.

    -- Terry

    1. Re:64 bit porting is more of a compiler problem by Anonymous Coward · · Score: 1, Informative

      I dunno what 'GNU toolchain' you're using, but I always get warnings about truncation in assignments and comparisons, and with GCC 4.x the signedness warnings are so strict as to almost be absurd (they may have crossed the line with char vs signed char vs unsigned char warnings--yes those are all three distinct types, regardless of whether plain char is effectively signed or unsigned).

      The `quad' type was a BSD anachronism, and in any event "Unix" specific (quad what? C doesn't guaranteed that char is an octet). Remember that C is not Unix, though Unix is C. `long long' could just as well be 128-bit on any platform, including some future Unix. C99 has specified fixed-width signed and unsigned integer types, so use them. They're optional in C99 but I believe mandatory in SUSv3, just like char must only be minimally 8 bits in C99, but exactly 8 bits in SUSv3.

      As for `long void *', what possible legitimate use could you have for that? If you're trying to employ a 64-bit pointer from 32-bit code you're already fubar'd. At that point you don't even have C code anymore, because by definition `void *' must be able to hold any and all pointer values. It's literally not a "void pointer" if there's another pointer type which is larger.

  24. GNU toolchain and not giving warnings by tlambert · · Score: 1
    GNU toolchain and not giving warnings

    You are incorrect.

    The following is some code that does not warn that the resolution of "long l" is potentially insufficient to store the value contained in "long ll":
    #include <stdio.h>
    #include <stdlib.h>
     
    int
    main(int ac, char *av[])
    {
        long long ll = 5;
        char buf[128];
        int constant;
        long l;
     
        printf("Enter constant: ");
        gets(buf);
        constant = atoi(buf);
        l = ll * constant;
     
        printf("l is %ld\n", l);
     
        return 0;
    }
    This is on an ILP32 machine with the current GCC 4.x. It also fails to warn in GCC 3.x, so this is not a "4.x branch thing".

    I would similarly expect a warning when using an integer as an lvalue for an expression containing a long when running on an ILP32 machine, but there is no warning - any overflow occurs silently.

    -- Terry
  25. Even well written code can have problems by tlambert · · Score: 2, Insightful

    Even well written code can have problems.

    Specifically, say I have a 64 bit platform capable of running both LP64 code and ILP32 (legacy) code.

    I use a shared memory segment to communicate between my legacy 32 bit applications, and it has internal use of pointers to perform self-reference on data.

    [Rather than complicating things, let's just assume that the pointers are internally based off the base address of the shared memory segment, rather than being based off of 0, so there is no requirement of mapping the memory into the same location in each process]

    I'm now adding a 64 bit computation engine (perhaps my application is a rendering system that uses plug-ins, and being able to work on large data sets with the large address space afforded to 64 bit processes is critical, but when it comes to displaying the results, I can live easily in a 32 bit address space, so I'm not trying to port my whole tool over to 64 bits).

    So now I have to deal with the internal pointers in the shared memory segment. I can do one of several things:

    (1) I can use structure coercion to treat the pointers as if they were integer offsets instead, and coerce them into pointers internally in the 64 bit code (on LP64, pointers are 64 bit).

    (2) I can intenrally store 64 bit pointers, rather than 32 bit pointers. This means I need the same round-tripping, but it can take place in the 32 bit applications, rather than the 64 bit applications, and the Integer representation is as "long long" as far as its concerned.

    (3) I can support either a "short void *" in 64 bit applications, or a "long void *" in 32 bit applciations.

    If I go with approach #3, I get to keep my type checking. With the other two approaches, I have explicit coercion, and I lose my type checking and boundary/range checking: the explicit casts quiet the warnings, even when they are used incorrectly.

    If I go further, and allow the segment to be mapped anywhere in memory, it may be mapped over 4G. I might also have relative base addressing (e.g. listerner converts), where I store the internal base address in the provider as part of the data being provided). This may sound like a strange scenario (e.g. it's like DCE RPC, in that it becomes the receiver's responsibility to convert, if a conversion is needed), but it's very useful. It has the following attributes:

    (a) If I use homogeneous consumer/providers, no conversion is necessary

    (b) My "work horse" application can do their work, and it's up to my "viewer" applciation to do the conversion; presumably, it's not doing much other than interacting with a slow human, so this ends up being the best division of labor

    (c) As time goes forward, the rest of my application is likely to migrate to 64 bit as well, so I get performance improvements over time, as the coversion requirements drop out.

    You could argue that because the program was not 64 bit clean, it's not "well written". You could also argue that losing the compiler warning checking is "OK, because it's your own fault for not porting everything" (if you didn't believe in closed source third party plugins over which you had no control).

    I would argue that you can expect someone to accurately predict future users of their software, and there's only so much work you can do to make sure that things don't break horribly at some arbitrary point in some arbitrary compilation environment.

    For the most part, we have to rely on our tools.

    And our tools do not tell us when this type of problem happens, because this type of problem is relatively new.

    -- Terry

  26. "didn't change the size of a word" by r00t · · Score: 1

    You are wrong, for some definitions of "word".

    To AMD and Intel, a word is 16 bits. This is seen in the Intel-style assembly that masm and nasm use.

    By the ELF binary specification, a word is 32-bit or 64-bit according to the platform. So the word size did change.

    The traditional idea, with a word being the size of a register, is like the ELF spec.

    The C programming language has no such thing. On both i386 and x86-64, sizeof(int)==4 and sizeof(long long)==8. On x86-64, sizeof(void*)==8. On i386, sizeof(void*)==4. On a Microsoft platform, sizeof(long)==4. On a non-Microsoft platform, sizeof(long)==sizeof(void*).

    1. Re:"didn't change the size of a word" by larry+bagina · · Score: 1

      for Microsoft, a WORD is 16 bits, a DWORD is 32 bits, and a QWORD is 64 bits.

      --
      Do you even lift?

      These aren't the 'roids you're looking for.

  27. 9-bit by r00t · · Score: 2, Informative

    char was 9-bit

    C requires at least 8 bits for char, so 6 isn't good enough.
    All types must be a multiple of the size of char, because
    sizeof(char) is 1 by definition and fractions are not OK.

    Valid sizes are thus: 9, 12, 18, 36

    The char-short-int-long progression may be one of:

    9,18,18,36 a likely choice
    9,18,27,36 this is the cool way: sizeof(int)==3
    9,18,36,36 a likely choice
    9,27,27,36
    9,27,36,36
    9,36,36,36 a likely choice
    12,24,24,36
    12,24,36,36
    12,36,36,36
    18,18,18,36
    18,18,36,36
    18,36,36,36
    36,36,36,36

    1. Re:9-bit by Stephen+Samuel · · Score: 1

      Probably 12/36/36, since characters are a multiple of 6 bits (either 6 or 12) and a 24 bit short just doesn't seem to make much sense.

      --
      Free Software: Like love, it grows best when given away.
    2. Re:9-bit by r00t · · Score: 1

      No, it was 9-bit. 12 was not used for some reason.

      24-bit shorts make perfect sense. I suspect they got smart about powers of two after making the mistake of using a 36-bit word, and decided not to have sizeof(long)==3.

      So char was 9 and long must have been 36. (long could have been bigger, but I doubt it was) The remaining two were most likely 18 or 36. These are most likely:

      9/18/36/36

      9/18/18/36

      Also, 9/36/36/36 was somewhat likely.

  28. Rely on compiler warnings by mi · · Score: 1
    Crank the warnings up as high as the OS' include files can bear and try recompiling.

    Then -- patiently fix them all. You know, you planned to do that for years. Do it before trying to build a 64-bit version.

    Then -- try the 64-bit version and fix all the warnings you missed before. void * to int conversions are my personal favorites...

    Resist the temptation to invent your own types, though (Mozilla's source tree is awful in this regard). Use the standard int32_t or uint64_t, where the number of bits matters -- a simple hardware-dependent int is usually more efficient.

    Make sure your next machine runs a 64-bit OS and gain practice by porting/fixing various free software to run on it :-)

    --
    In Soviet Washington the swamp drains you.
  29. Portable Code NO!, Crash Code YES! Fuck you! by Anonymous Coward · · Score: 0
    Question: What to do with the 100 old 32-bit PCs?
    Answer: To follow programming 32-bit ASM, quick and dirty, don't write C stupid.

    Question: And the 20 Athlon64 for the small-enterprises?
    Answer: To follow programming 32-bit ASM, don't write C stupid, don't write 64-bit ASM.
    Answer: To enterprises, don't permit them to build a 64-bit cluster!!!

    Thanks for the 2 GiB RAM limitation for the Athlon, Pentium and Athlon64!!!

    Thanks, nobody uses 4 or 8 or 16 or 32 GiB of virtual memory, BACK TO 32-bit WORLD!!!.

  30. Fortran 90/95 by IvyKing · · Score: 1
    Which reminds me of something... Isn't it time for C and its likes to let us specify explicitly how many bits we want for a variable? I would like to tell the compiler that a variable should be _exactly_ 32 bits and another one _at least_ 64 bits.

    Sounds like you want the "kind" functionality of Fortran 90.

    Back in the bad old days, a REAL in Fortran could be anywhere from 32 to 64 bits - a program that ran fine using REAL on a CDC-6600 (60 bits) might die horribly using REAL on an IBM 360 (32 bits but using hexadecimal arithemtic).

  31. DEC or Univac - not CDC by IvyKing · · Score: 1
    I have no idea what a 36 bit signed-magnitude integer mainfraim (( Yeah, they really existed -- CDC made them ))

    CDC made 48 bit machines (1604 and 3000 series) and 60 bit machines (6000 series, 7600 and some Cyber's) but not a 36 bit machine AFAIK. The 6600 had 60 bit reals and long ints, 18 bit short ints, 12 bit words for the peripheral processors - a real PITA for C.

  32. My experience by ananamouse · · Score: 1

    I had to change a bunch of 'int' to 'long' to get something to compile.

    1. Re:My experience by gatkinso · · Score: 1

      That's great... for HelloWorld.c.

      Now... get it to actually work, be backwards compatible with your 32 bit compiler, and do something even slightly nontrivial. Say, pack a struct into a datagram on your 64 bit host, send it to a 32 bit host, and unpack it into a struct with the same byte alignment (using the same code on both hosts).

      --
      I am very small, utmostly microscopic.
  33. Re:/lib was botched, so yes you must port librarie by copper · · Score: 1
    Been using gentoo on amd64 for almost a year now, and I was wondering if there is a technical reason why it's:
    /lib
    /lib32
    /lib64 -> lib
    instead of:
    /lib32
    /lib64
    /lib -> /lib64
    One martini on an empty stomach into the night and my desire to apply any analytical thought is out the window... at least until tomorrow...