shap@shasta.Stanford.EDU (shap) (04/27/91)
Several companies have announced or are known to be working on 64 bit architectures. It seems to me that 64 bit architectures are going to introduce some nontrivial problems with C and C++ code. I want to start a discussion going on this topic. Here are some seed questions: 1. Do the C/C++ standards need to be extended to cover 64-bit environments, or are they adequate as-is? 2. If a trade-off has to be made between compliance and ease of porting, what's the better way to go? 3. If conformance to the standard is important, then the obvious choices are short 16 bits int 32 bits long 64 bits void * 64 bits How bad is it for sizeof(int) != sizeof(long). 4. Would it be better not to have a 32-bit data type and to make int be 64 bits? If so, how would 32- and 64- bit programs interact? Looking forward to a lively exchagne...
torek@elf.ee.lbl.gov (Chris Torek) (04/27/91)
In article <168@shasta.Stanford.EDU> shap@shasta.Stanford.EDU (shap) writes: >How bad is it for sizeof(int) != sizeof(long). This has been the case on PDP-11s for over 20 years. It does cause problems---there is always software that makes invalid assumptions---but typically long-vs-int problems, while rampant, are also easily fixed. -- In-Real-Life: Chris Torek, Lawrence Berkeley Lab CSE/EE (+1 415 486 5427) Berkeley, CA Domain: torek@ee.lbl.gov
sarima@tdatirv.UUCP (Stanley Friesen) (04/28/91)
In article <168@shasta.Stanford.EDU> shap@shasta.Stanford.EDU (shap) writes: >Several companies have announced or are known to be working on 64 bit >architectures. It seems to me that 64 bit architectures are going to >introduce some nontrivial problems with C and C++ code. >1. Do the C/C++ standards need to be extended to cover 64-bit >environments, or are they adequate as-is? They are adequate as is. They make only minimum requirements for a conforming implementation. In particular, there is no reason why you cannot have 64 bit long's (which is what I would do) or even 64 bit int's. And you could easily have 64 and 128 bit floating point types (either as 'float' and 'double' or as 'double' and 'long double' - both approaches are standard conforming). >2. If a trade-off has to be made between compliance and ease of >porting, what's the better way to go? In writing a new compiler from scratch (or even mostly from scratch) there is no question, full ANSI compliance is absolutely necessary. [An ANSI compiler may itself be less portable, but it allows the application programers to write portable code more easily]. In porting an existing compiler, do whatever seems most practical. >3. If conformance to the standard is important, then the obvious >choices are > short 16 bits > int 32 bits > long 64 bits > void * 64 bits OR: short 32 bits int 64 bits long 64 bits OR: short 32 bits int 32 bits long 64 bits Any one of the above may be the most appropriate depending on the instruction set. If there are no instructions for 16 bit quantities then using 16 bit short's is a big loss. And if it really is set up as a hybrid 32/64 bit architecture, even the last may be useful. [For instance, the Intel 80X86 series chips are hybrid 16/32 bit architectures, so both 16 and 32 bit ints make sense]. >How bad is it for sizeof(int) != sizeof(long). Not particularly. There are already millions of machines where this is true - on PC class machines running MS-DOS sizeof(int) == sizeof(short) for most existing compilers, (that is the sizes are 16, 16, 32). [And on Bull mainframes, unless things have changed, all three are the same size]. >4. Would it be better not to have a 32-bit data type and to make int >be 64 bits? If so, how would 32- and 64- bit programs interact? Programs on different machines should not talk to each other in binary. [See the long, acrimonious discussions about binary I/O right here]. And as long as you use either ASCII text or XDR representation for data exchange, there is no problem. Howver, I would be more likely to skip the 16 bit type than the 32 bit type. (Of course if the machine has a 16 bit add and not a 32 bit one ...). In short the idea is that C should translate as cleanly as possible into the most natural data types for the machine in question. This is what the ANSI committee had in mind. -- --------------- uunet!tdatirv!sarima (Stanley Friesen)
bhoughto@pima.intel.com (Blair P. Houghton) (04/28/91)
In article <168@shasta.Stanford.EDU> shap@shasta.Stanford.EDU (shap) writes: >It seems to me that 64 bit architectures are going to >introduce some nontrivial problems with C and C++ code. Nope. They're trivial if you didn't assume 32-bit architecture, which you shouldn't, since many computers still have 36, 16, 8, etc.-bit architectures. >I want to start a discussion going on this topic. Here are some seed >questions: Here's some fertilizer (but most of you consider it that way, at any time :-) ): >1. Do the C/C++ standards need to be extended to cover 64-bit >environments, or are they adequate as-is? The C standard allows all sorts of data widths, and specifies a scad of constants (#defines, in <limits.h> to let you use these machine-specific numbers in your code, anonymously. >2. If a trade-off has to be made between compliance and ease of >porting, what's the better way to go? If you're compliant, you're portable. >3. If conformance to the standard is important, then the obvious >choices are > > short 16 bits > int 32 bits > long 64 bits > void * 64 bits The suggested choices are: short <the shortest integer the user should handle; >= 8 bits> int <the natural width of integer data on the cpu; >= a short> long <the longest integer the user should handle; >= an int> void * <long enough to specify any location legally addressable> There's no reason for an int to be less than the full register-width, and no reason for an address to be limited to the register width. An interesting side-effect of using the constants is that you never need to know the sizes of these things on your own machine; i.e., use CHAR_BIT (the number of bits in a char) and `sizeof int' (the number of chars in an int) and you'll never need to know how many bits an int contains. >How bad is it for sizeof(int) != sizeof(long). It's only bad if you assume it's not true. (I confess: I peeked. I saw Chris' answer, and I'm not going to disagree.) >4. Would it be better not to have a 32-bit data type and to make int >be 64 bits? If so, how would 32- and 64- bit programs interact? Poorly, if at all. Data transmission among architechures with different bus sizes is a hairy issue of much aspirin. The only portable method is to store and transmit the data in some width-independent form, like morse-code or a text format (yes, ascii is a 7 or 8 bits wide, but it's a _common_ form of data-width hack, and if all else fails, you can hire people to read and type it into your machine). >Looking forward to a lively exchagne... --Blair "Did anyone NOT bring potato salad?"
marc@dumbcat.sf.ca.us (Marco S Hyman) (04/29/91)
In article <224@tdatirv.UUCP> sarima@tdatirv.UUCP (Stanley Friesen) writes: > In article <168@shasta.Stanford.EDU> shap@shasta.Stanford.EDU (shap) writes: > > short 16 bits > > int 32 bits > > long 64 bits > > void * 64 bits > > OR: > short 32 bits > int 64 bits > long 64 bits > > OR: > short 32 bits > int 32 bits > long 64 bits I hope not -- at least not without some other way of describing a 16-bit value. 64-bit architecture machines will still have to communicate with other machines that do support 16-bit values. Swapping bytes between big and little endian machines is bad enough. Think about the overhead of converting a pair of bytes to a 16-bit value. > Any one of the above may be the most appropriate depending on the > instruction set. If there are no instructions for 16 bit quantities > then using 16 bit short's is a big loss. Hmmm. How would such a processor communicate with hardware devices requiring 16-bit I/O? How would a structure that maps an external device's registers be coded if the registers are 16-bits wide? If there is a way to do these things then a 16-bit wide data type is probably necessary. -- // marc // home: marc@dumbcat.sf.ca.us pacbell!dumbcat!marc // work: marc@ascend.com uunet!aria!marc
shap@shasta.Stanford.EDU (shap) (04/29/91)
In article <295@dumbcat.sf.ca.us> marc@dumbcat.sf.ca.us (Marco S Hyman) writes: >In article <224@tdatirv.UUCP> sarima@tdatirv.UUCP (Stanley Friesen) writes: > > If there are no instructions for 16 bit quantities > > then using 16 bit short's is a big loss. > >Hmmm. How would such a processor communicate with hardware devices requiring >16-bit I/O? The answer, given the machine he poses, is that it doesn't, since it doesn't support 16 bit ops. You could build such a machine, provided you were willing to do all the peripherals yourself (I'm not recommending). However, there is a more compelling argument for 16 bit types in RPC, extended precision math routines, etc. 'short' has the (un?)fortunate property that it has been 16 bits on almost every machine known to man, and a depressing amount of code appears to make the sizeof(short) == 16 bits assumption.
phil@ux1.cso.uiuc.edu (Phil Howard KA9WGN) (04/29/91)
shap@shasta.Stanford.EDU (shap) writes: >2. If a trade-off has to be made between compliance and ease of >porting, what's the better way to go? User selectable. >3. If conformance to the standard is important, then the obvious >choices are > short 16 bits > int 32 bits > long 64 bits > void * 64 bits That depends on the natural address size of the machine. If the machine uses 32 bit addresses, then (void *) should be 32 bits. I would not want my address arrays taking up more memory than is needed. Is it really necessary that sizeof(void *) == sizeof(long)? >How bad is it for sizeof(int) != sizeof(long). Would not bother me as long as sizeof(int) <= sizeof(long) >4. Would it be better not to have a 32-bit data type and to make int >be 64 bits? If so, how would 32- and 64- bit programs interact? Again it would depend on the machine. If the machine has both 32 bit and 64 bit operations, then do include them. If a 32 bit operation is unnatural to the machine, then don't. If it has 16 bit operations then that makes sense for short. -- /***************************************************************************\ / Phil Howard -- KA9WGN -- phil@ux1.cso.uiuc.edu | Guns don't aim guns at \ \ Lietuva laisva -- Brivu Latviju -- Eesti vabaks | people; CRIMINALS do!! / \***************************************************************************/
jac@gandalf.llnl.gov (James A. Crotinger) (04/29/91)
Anyone want to comment on experiences with Crays? I believe the C compilers have sizeof(int) = sizeof(short) = sizeof(long) == 46 or 64 bits, depending on a compile time flag (Crays can do 46 bit integer arithmetic using the vectorizing floating point processors, so that is the default). Binary communications between Crays and other computers is something I haven't done, mostly because Cray doesn't support IEEE floating point. Jim -- ----------------------------------------------------------------------------- James A. Crotinger Lawrence Livermore Natl Lab // The above views jac@moonshine.llnl.gov P.O. Box 808; L-630 \\ // are mine and are not (415) 422-0259 Livermore CA 94550 \\/ necessarily those of LLNL
campbell@redsox.bsw.com (Larry Campbell) (04/29/91)
In article <1991Apr29.050715.22968@ux1.cso.uiuc.edu> phil@ux1.cso.uiuc.edu (Phil Howard KA9WGN) writes:
->3. If conformance to the standard is important, then the obvious
->choices are
-
-> short 16 bits
-> int 32 bits
-> long 64 bits
-> void * 64 bits
-
-That depends on the natural address size of the machine. If the
-machine uses 32 bit addresses, then (void *) should be 32 bits.
-I would not want my address arrays taking up more memory than is
-needed.
-
-Is it really necessary that sizeof(void *) == sizeof(long)?
Of course not.
We're currently porting a largish (150K lines) program to a machine
on which:
short (dunno, not at work now so I can't check)
int 32 bits
long 32 bits
void * 128 bits
Thank *god* it has a fully-compliant ANSI compiler.
For extra credit: can you guess what machine this is?
--
Larry Campbell The Boston Software Works, Inc., 120 Fulton Street
campbell@redsox.bsw.com Boston, Massachusetts 02109 (USA)
mvm@jedi.harris-atd.com (Matt Mahoney) (04/29/91)
When I need to specify bits, I'm usually forced to make the following assumptions: char 8 bits short 16 bits long 32 bits since this is true on most machines. Anything else would probably break a lot of code. ------------------------------- Matt Mahoney, mvm@epg.harris.com #include <disclaimer.h>
warren@cbnewsh.att.com (warren.a.montgomery) (04/29/91)
There are probably a lot of hidden assumptions in programs that sizeof(short)==2 and sizeof(long)==4 at this point, so any assignment of meanings on a 64 bit machine (unless you invent type "long long" for 64 bits and leave long and short at 32 and 16) will cause some pain. All this raises questions about C/C++'s philosophy of integer type specification, which no doubt dates from the days where all machines had only 2 and 4 byte integers. C is unusual in my experience at least in allowing the programmer explicit control over how large integer variables will be, but not tying the specification down to a specific size or value. In PL/1, for example, you explicitly state how many bits you want in a binary integer. This gives you much more predictability than "short" and "long", which are more like hints to the compiler, but I suspect that the extra precision frequently gets in the way. (Both the programmer and the machine wind up doing extra work when an integer that needs to be big enough to hold 1,000,000 gets declared to be 36 bits on a 36 bit machine (simply because the programmer knew that was a magic number, and then ported to a 32 bit machine.) I don't even know if it is possible in C to write a declaration guaranteed to produce an integer of a specific size (in bits or bytes) in a machine-independent way. There are lots of ways a programmer may want to declare an integer: 1 Any convenient and reasonable size. 2 Any convenient size large enough to represent X. 3 The smallest convenient size large enough to represent X. 4 Exactly Y bits or bytes long. 5 Exactly the same size as datatype Z 1 seems to be the intent of "int". "short", "long", and "char" can be used to accomplish 4 for certain values of Y (which differ on each machine). The number of functions written to manipulate 24 bit integers, though, is evidence that this is an imperfect solution. 2,3, and 5 aren't directly expressable in C, but people frequently mean this and use hidden assumptions about how big short and long are in order to do it. There are probably other ways that would be useful to define the size of some integer type, but these will do for a start. How are things like this best expressed in C or C++? Do other languages provide better overall solutions? -- Warren Montgomery att!ihlpf!warren
robertk@lotatg.lotus.com (Robert Krajewski) (04/29/91)
Actually, there's one thing that people didn't mention -- the feasibility of bigger lightweight objects. I'd assume that any processor that advertised a 64-bit archtitecture would be able to efficiently move around 64 bits at a time, so it would be very cheap to move 8-byte (excuse me, octet) objects around by copying.
barmar@think.com (Barry Margolin) (04/29/91)
In article <295@dumbcat.sf.ca.us> marc@dumbcat.sf.ca.us (Marco S Hyman) writes: >In article <224@tdatirv.UUCP> sarima@tdatirv.UUCP (Stanley Friesen) writes: > > Any one of the above may be the most appropriate depending on the > > instruction set. If there are no instructions for 16 bit quantities > > then using 16 bit short's is a big loss. > >Hmmm. How would such a processor communicate with hardware devices requiring >16-bit I/O? How would a structure that maps an external device's registers be >coded if the registers are 16-bits wide? If there is a way to do these things >then a 16-bit wide data type is probably necessary. You could map each register into the bottom (or top, or middle, or whatever) 16 bits of adjacent memory words or half-words. Or, if you want to be really perverse, you make every fourth bit in the word map into a bit in the register. :{) -- Barry Margolin, Thinking Machines Corp. barmar@think.com {uunet,harvard}!think!barmar
turk@Apple.COM (Ken "Turk" Turkowski) (04/30/91)
shap@shasta.Stanford.EDU (shap) writes: >3. If conformance to the standard is important, then the obvious >choices are > short 16 bits > int 32 bits > long 64 bits > void * 64 bits >4. Would it be better not to have a 32-bit data type and to make int >be 64 bits? If so, how would 32- and 64- bit programs interact? It is necessary to have 8, 16, and 32-bit data types, in order to be able to read data from files. I would suggest NOT specifying a size for the int data type; this is supposed to be the most efficient integral data type for a particular machine and compiler. A lot of programs rely on the fact that nearly all C implementations have a 32-bit long int. I would suggest: short 16 bits long 32 bits long long 64 bits int UNSPECIFIED void * UNSPECIFIED This is patterned after ANSI floating-point extensions to accommodate an extended format (i.e. "long double"). How about "double long", because it really is two longs? (Donning flame retardent suit). What then would 128-bit ingeter be? long long long? double double long? long double long? quadruple long? How about the Fortran method: int*8? Another proposal would be to invent a new word, like "big", "large", "whopper", "humongous", "giant", "extra", "super", "grand", "huge", "jumbo", "broad", "vast", "wide", "fat", "hefty", etc. Whatever chaice is made, there should be ready extensions to 128 and 256 bit integers, as well as 128 and 256-bit floating point numbers. P.S. By the way is there an analagous word for floating-point numbers as int does for integers? -- Ken Turkowski @ Apple Computer, Inc., Cupertino, CA Internet: turk@apple.com Applelink: TURK UUCP: sun!apple!turk
john@sco.COM (John R. MacMillan) (04/30/91)
shap <shap@shasta.Stanford.EDU> writes: |Several companies have announced or are known to be working on 64 bit |architectures. It seems to me that 64 bit architectures are going to |introduce some nontrivial problems with C and C++ code. In a past life I did a fair amount of work with C on a 64 bit architecture, the C/VE compiler on NOS/VE. C/VE was a pre-ANSI compiler, but many of the comments I think still apply. C/VE had 64 bit ints and longs, 32 bit shorts, 8 bit chars, and 48 bit pointers (as an added bonus, the null pointer was not all bits zero, but that's another headache entirely; ask me how many times I've wanted to strangle a programmer who used bzero() to clear structures that have pointers in them). |I want to start a discussion going on this topic. Here are some seed |questions: | |1. Do the C/C++ standards need to be extended to cover 64-bit |environments, or are they adequate as-is? The C standard certainly is; it's obvious a lot of effort went into making sure it would be. |2. If a trade-off has to be made between compliance and ease of |porting, what's the better way to go? I don't think there's any reason to trade off compliance with standards; if you want to trade off ease of porting versus exploiting the full power of the architecture that's another question. The answer is going to be different for different people. If you make the only 64 bit data type be ``long long'' or some such, it will make life much easier on porters, but most of the things you port then won't take advantage of having 64 bit data types... |3. If conformance to the standard is important, then the obvious |choices are | | short 16 bits | int 32 bits | long 64 bits | void * 64 bits This isn't really a conformance issue. The idea is to make the machine's natural types fit the C types well. However, if the architecture can support all these sizes easily, then for ease of porting it would be nice to have all of the common sizes available. Many (often poorly written) C programs depend on, say, short being 16 bits, and having a 16 bit data type is the easiest way to port such programs. One problem with 32 bit ints and 64 bit pointers is that a lot of (bad) code assumes you can put a pointer into an int, and vice versa. As an aside, using things like ``typedef int int32'', is not always the answer, especially if you don't tell the porter (or are inconsistent about) whether this should be an integer data type that is _exactly_ 32 bits or _at least_ 32 bits. |How bad is it for sizeof(int) != sizeof(long). The C/VE compiler had sizeof(int) == sizeof(long) so I can't comment on that one in particular, but... |4. Would it be better not to have a 32-bit data type and to make int |be 64 bits? If so, how would 32- and 64- bit programs interact? ...there is a lot of badly written code out there, and no matter what you do, you'll break somebody's bogus assumptions. In particular a lot of code makes assumptions about pointer sizes, whether they'll fit in ints, and whether you can treat them like ints. Expect porting to 64 bit architectures to be work, because it is.
sarima@tdatirv.UUCP (Stanley Friesen) (04/30/91)
In article <295@dumbcat.sf.ca.us> marc@dumbcat.sf.ca.us (Marco S Hyman) writes: >I hope not -- at least not without some other way of describing a 16-bit >value. 64-bit architecture machines will still have to communicate with other >machines that do support 16-bit values. Swapping bytes between big and little >endian machines is bad enough. Think about the overhead of converting a pair >of bytes to a 16-bit value. Binary communication between machines should use XDR *not* C structures. As for how to do it, see below. >Hmmm. How would such a processor communicate with hardware devices requiring >16-bit I/O? How would a structure that maps an external device's registers be >coded if the registers are 16-bits wide? If there is a way to do these things >then a 16-bit wide data type is probably necessary. Well, two seperate points. First, if the machine does not have 16-bit operations in its instruction set, then 16-bit I/O registers will probably be wired into 32-bit pseudo-words (with the high-order 16-bits wired into the bit-bucket). Remember, the lack of 16-bit instructions would mean that 16-bit bus transfers are not possible. Secondly, there are two possible implementations of this sort of thing. First, C has this concept called bit fields, which can be of any size you want - so if you *must* have a 16-bit quantity, use a 16-bit bit field. (This also answers the previous objection - if you *must* be machine dependent, at least make it stand out). Alternatively, for the I/O register case, just send two sequential bytes. (Unless the machine does not have byte adressing - which is quite possible in a 64-bit super-computer). Remember, binary compatibility between machines is a very shaky proposition at best, so it is better not to depend on it at all. -- --------------- uunet!tdatirv!sarima (Stanley Friesen)
wmm@world.std.com (William M Miller) (04/30/91)
bhoughto@pima.intel.com (Blair P. Houghton) writes: > The suggested choices are: > > short <the shortest integer the user should handle; >= 8 bits> Actually, ANSI requires at least 16 bits for shorts (see SHRT_MIN and SHRT_MAX in <limits.h>, X3.159-1989 2.2.4.2.1). -- William M. Miller, Glockenspiel, Ltd. wmm@world.std.com
sarima@tdatirv.UUCP (Stanley Friesen) (04/30/91)
In article <1991Apr29.140256.27605@cbnewsh.att.com> warren@cbnewsh.att.com (warren.a.montgomery) writes: <There are probably a lot of hidden assumptions in programs that <sizeof(short)==2 and sizeof(long)==4 at this point, so any <assignment of meanings on a 64 bit machine True, but such code is lkely to cause pain at any time anyway, Too many currently *existing* machines violate this assumption. < I don't even know if it is possible in C to write a <declaration guaranteed to produce an integer of a specific size <(in bits or bytes) in a machine-independent way. Well you can come rather close, though you need to do some special stuff to do arithmetic on them: struct { signed long value:SIZE; }; will will give you SIZE bits on almost all machines. [To do arithmetic you must explicitely access the value member]. Remember if *bits* are important use bitfields <There are lots of ways a programmer may want to declare an integer: < <1 Any convenient and reasonable size. Declare this an int. <2 Any convenient size large enough to represent X. Use either short or long depending on whether 16 bits is sufficient or not. [Note that a minimum requirement of a certain number of bits *is* portable, short's must be at least 16 bits in size, though they may be larger]. <3 The smallest convenient size large enough to represent X. Harder to do portably. I would suggest using a typedef and a machine-specific header file for each architecture. <4 Exactly Y bits or bytes long. The only portable way to do this is bitfields. [On a *given* machine you may use a basic integer type if it is the right size]. <5 Exactly the same size as datatype Z < < 2,3, and 5 aren't directly expressable in C, but people <frequently mean this and use hidden assumptions about how big <short and long are in order to do it. But 2. *is* possible. You can assume that a short is *at* *least* 16 bits, and a long is *at* *least* 32 bit. You just may get more than you absolutely need. (And of course char is at least 8 bits). Just as long as you do not assume that any type is exactly some size you are safe. -- --------------- uunet!tdatirv!sarima (Stanley Friesen)
phil@ux1.cso.uiuc.edu (Phil Howard KA9WGN) (05/01/91)
mvm@jedi.harris-atd.com (Matt Mahoney) writes: >When I need to specify bits, I'm usually forced to make the >following assumptions: > char 8 bits > short 16 bits > long 32 bits >since this is true on most machines. Anything else would probably break >a lot of code. What would break if you did: char 8 bits short 16 bits int 32 bits long 64 bits where any pointer or pointer difference would fit in 32 bits? -- /***************************************************************************\ / Phil Howard -- KA9WGN -- phil@ux1.cso.uiuc.edu | Guns don't aim guns at \ \ Lietuva laisva -- Brivu Latviju -- Eesti vabaks | people; CRIMINALS do!! / \***************************************************************************/
phil@ux1.cso.uiuc.edu (Phil Howard KA9WGN) (05/01/91)
john@sco.COM (John R. MacMillan) writes: >One problem with 32 bit ints and 64 bit pointers is that a lot of >(bad) code assumes you can put a pointer into an int, and vice versa. >...there is a lot of badly written code out there, and no matter what >you do, you'll break somebody's bogus assumptions. In particular a >lot of code makes assumptions about pointer sizes, whether they'll fit >in ints, and whether you can treat them like ints. For how long should we keep porting code, especially BAD CODE? This sounds a lot like school systems that keep moving failing students up each year and we know what that results in. IMHO, no code older than 8 years should be permitted to be ported and if it is found to be "bad" code then it must have been written more than 8 years ago. -- /***************************************************************************\ / Phil Howard -- KA9WGN -- phil@ux1.cso.uiuc.edu | Guns don't aim guns at \ \ Lietuva laisva -- Brivu Latviju -- Eesti vabaks | people; CRIMINALS do!! / \***************************************************************************/
peter@llama.trl.OZ.AU (Peter Richardson - NSSS) (05/01/91)
In article <4068@inews.intel.com>, bhoughto@pima.intel.com (Blair P. Houghton) writes: > In article <168@shasta.Stanford.EDU> shap@shasta.Stanford.EDU (shap) writes: > >It seems to me that 64 bit architectures are going to > >introduce some nontrivial problems with C and C++ code. > > Nope. They're trivial if you didn't assume 32-bit architecture, > which you shouldn't, since many computers still have 36, 16, 8, > etc.-bit architectures. > > >I want to start a discussion going on this topic. Here are some seed > >questions: Hmmm. As I understand it. if you want to write truly portable code, you should never make assumptions about sizeof any integral types. We have a local header file on each machine type defining Byte, DoubleByte etc. For example, on sun4: typedef unsigned char Byte; // always a single byte typedef unsigned short DoubleByte; // always two bytes typedef unsigned long QuadByte; // always four bytes If you want to use an int, use an int. If you want to use a 16 bit quantity, use a DoubleByte. To port to new machines, just change the header file. Purists may prefer "Octet" to "Byte". It is up to the platform/compiler implementation to determine the appropriate sizeof integral types. It should not be part of the language. > > Poorly, if at all. Data transmission among architechures > with different bus sizes is a hairy issue of much aspirin. > The only portable method is to store and transmit the data > in some width-independent form, like morse-code or a text > format (yes, ascii is a 7 or 8 bits wide, but it's a > _common_ form of data-width hack, and if all else fails, > you can hire people to read and type it into your > machine). There is an international standard for doing this, called Abstract Syntax Notation One (ASN.1), defined by ISO. It is based on the CCITT standards X.208 and X.209 (I think). It is more powerful than either of the proprietary standards XDR or NDR. Compilers are used to translate ASN.1 data descriptions into C/C++ structures, and produce encoder/decoders. --- Peter Richardson Phone: +61 3 541-6342 Telecom Research Laboratories Fax: +61 3 544-2362 Snail: GPO Box 249, Clayton, 3168 Victoria, Australia Internet: p.richardson@trl.oz.au X400: g=peter s=richardson ou=trl o=telecom prmd=telecom006 admd=telememo c=au
bhoughto@pima.intel.com (Blair P. Houghton) (05/01/91)
In article <1991Apr30.140217.7065@world.std.com> wmm@world.std.com (William M Miller) writes: >bhoughto@pima.intel.com (Blair P. Houghton) writes: >> short <the shortest integer the user should handle; >= 8 bits> >Actually, ANSI requires at least 16 bits for shorts (see SHRT_MIN and >SHRT_MAX in <limits.h>, X3.159-1989 2.2.4.2.1). I had my brain packed-BCD mode that day, apparently :-/... The minimum sizes for the four integer types are: char 8 bits short 16 int 16 long 32 Other than that, one need only ensure that short, int, and long are multiples of the size of a char, e.g., 9, 27, 36, 36. --Blair "Hike!"
dlw@odi.com (Dan Weinreb) (05/01/91)
In article <1991May1.012242.26211@ux1.cso.uiuc.edu> phil@ux1.cso.uiuc.edu (Phil Howard KA9WGN) writes:
From: phil@ux1.cso.uiuc.edu (Phil Howard KA9WGN)
Date: 1 May 91 01:22:42 GMT
References: <168@shasta.Stanford.EDU> <1991Apr29.211937.10865@sco.COM>
Organization: University of Illinois at Urbana
IMHO, no code older than 8 years should be permitted to be ported
I see from the Organization field in your mail header that you're from
a university.
turk@Apple.COM (Ken "Turk" Turkowski) (05/01/91)
jac@gandalf.llnl.gov (James A. Crotinger) writes: > Anyone want to comment on experiences with Crays? I believe the C >compilers have sizeof(int) = sizeof(short) = sizeof(long) == 46 or 64 >bits, depending on a compile time flag (Crays can do 46 bit integer >arithmetic using the vectorizing floating point processors, so that is >the default). > Binary communications between Crays and other computers is something >I haven't done, mostly because Cray doesn't support IEEE floating point. Crays are a pain. Structures are padded to 64 bits, so you waste a lot of memory in arrays if your structures only have 16 bits. I thought the number was 48 bits, but you might be right. I seem to recall that logical operations couldn't work with 64 bits, but arithmetic operations could, or vice versa. If you want to write out a number between 8 and 64 bits, you need to break it into bytes. As long as you're doing this, you may as well write the proper endian. It's not too bad to write a cray FP to IEEE converter. One of the basic rules of machine independent I/O, though, is to not write structures out directly, but rather to go through a procedure for each element. Same goes for input. -- Ken Turkowski @ Apple Computer, Inc., Cupertino, CA Internet: turk@apple.com Applelink: TURK UUCP: sun!apple!turk
jerry@talos.npri.com (Jerry Gitomer) (05/01/91)
mvm@jedi.harris-atd.com (Matt Mahoney) writes:
:When I need to specify bits, I'm usually forced to make the
:following assumptions:
: char 8 bits
: short 16 bits
: long 32 bits
:since this is true on most machines. Anything else would probably break
:a lot of code.
We are caught between the rock (wanting to take *full* advantage of
the new wider register and memory data path machines 64 bits today,
128 tomorrow, and 256 the day after tomorrow) and the hard place
(wanting to preserve code that was handcrafted to the
idiosyncracies of prior generation hardware). Our choices are
simple -- throw the performance of the new machines out the window
or spend the time and money required to fix up the code so that it
complies with the standard. (Sure, standards aren't cast in
concrete, but their life exptancy exceeds that of today's typical
computer system).
IMHO (now isn't that an arrogant phrase? :-) ) it is better to fix
up the offending programs now than to do it later. I say this
because I presume that salaries will continue to increase, which
will make it more expensive to fix things up later, and because
staff turnover leads to a decrease over time in knowledge of the
offending programs.
--
Jerry Gitomer at National Political Resources Inc, Alexandria, VA USA
I am apolitical, have no resources, and speak only for myself.
Ma Bell (703)683-9090 (UUCP: ...uunet!uupsi!npri6!jerry )
cadsi@ccad.uiowa.edu (CADSI) (05/01/91)
From article <13261@goofy.Apple.COM>, by turk@Apple.COM (Ken "Turk" Turkowski): > jac@gandalf.llnl.gov (James A. Crotinger) writes: > > >> Anyone want to comment on experiences with Crays? I believe the C >>compilers have sizeof(int) = sizeof(short) = sizeof(long) == 46 or 64 >>bits, depending on a compile time flag (Crays can do 46 bit integer >>arithmetic using the vectorizing floating point processors, so that is >>the default). > >> Binary communications between Crays and other computers is something >>I haven't done, mostly because Cray doesn't support IEEE floating point. > > Crays are a pain. Structures are padded to 64 bits, so you waste a lot > of memory in arrays if your structures only have 16 bits. > > I thought the number was 48 bits, but you might be right. I seem to recall > that logical operations couldn't work with 64 bits, but arithmetic operations > could, or vice versa. >... to further these comments note that on a CRAY, a (char *) is a bit-packed structure itself. In particular, the lower 48 bits are a pointer to the word in memory where the character exists. The top 3 bits of the 64-bit pointer are an index to the byte of the word of the actual character. Thus, an (int *) cannot be conveniently cast to a (char *). I hate it when that happens. |----------------------------------------------------------------------------| |Tom Hite | The views expressed by me | |Manager, Product development | are mine, not necessarily | |CADSI (Computer Aided Design Software Inc. | the views of CADSI. | |----------------------------------------------------------------------------|
rli@buster.stafford.tx.us (Buster Irby) (05/02/91)
turk@Apple.COM (Ken "Turk" Turkowski) writes: >It is necessary to have 8, 16, and 32-bit data types, in order to be able >to read data from files. I would suggest NOT specifying a size for the int >data type; this is supposed to be the most efficient integral data type >for a particular machine and compiler. You assume a lot about the data in the file. Is it stored in a specific processor format (ala Intel vs Motorolla)? My experience has been that binary data is not portable anyway.
daves@ex.heurikon.com (Dave Scidmore) (05/02/91)
In article <6157@trantor.harris-atd.com> mvm@jedi.UUCP (Matt Mahoney) writes: >When I need to specify bits, I'm usually forced to make the >following assumptions: > > char 8 bits > short 16 bits > long 32 bits > >since this is true on most machines. Anything else would probably break >a lot of code. I'm supprised nobody has mentioned that the real solution to this kind of portability problem is for the original programmer to use the definitions in "types.h" that tell you how big chars, shorts, ints, and longs are. I know that a lot of existing code does not take advantage of the ability to use typdefs or #defines to alter the size of key variables or adjust for numbers of bits for each, but doing so would help prevent the kinds of portability problems mentioned. I always urge people when writing their own code to be aware of size dependent code and either use the existing "types.h", or make their own and use it to make such code more portable. This won't help you when porting someone elses machine dependant (and dare I say poorly written) code, but the next guy who has to port your code will have an easier time of it. -- Dave Scidmore, Heurikon Corp. dave.scidmore@heurikon.com
daves@ex.heurikon.com (Dave Scidmore) (05/02/91)
warren@cbnewsh.att.com (warren.a.montgomery) writes: >There are probably a lot of hidden assumptions in programs that >sizeof(short)==2 and sizeof(long)==4 at this point, so any >assignment of meanings on a 64 bit machine (unless you invent type >"long long" for 64 bits and leave long and short at 32 and 16) >will cause some pain. > >All this raises questions about C/C++'s philosophy of integer type >specification, which no doubt dates from the days where all >machines had only 2 and 4 byte integers. I doubt such a day ever existed. The early K&R book refered to machines with 9 bit chars and 36 bit integers when describing the number of bits in various quantities. >... How are things like this best >expressed in C or C++? >Do other languages provide better overall solutions? The important factor you have to keep in mind when dealing with C or C++ is that they both attempt to keep the match between C expressions and machine instructions as close as possible. This results in more efficient code and faster execution, one of the strong points of C. In this respect C has often been refered to as a glorified assembly language since it allows you to do use level language constructs, but still allows you to use types and constructs which have a high degree of coorelation with the machine instruction set. This approach places the burden for portability on the programmer rather than on the compiler with the end result that the compiler need not waste time dealing with variables that are of a size that is not a good match to types supported by the the underlying machine. I have yet to see a piece of code that depends on sizeof(built in type) == X that could not be written to be portable across almost any machine (except where no machine type is large enough to hold the range of values needed). One approach is to isolate dependancies using typedefs like: typedef Int32Bit long; typedef Int16Bit short; typedef Int8Bit char; then use the appropriate type for the situation. This approach fails when working on machines that are not based on 8 bit bytes, or that have odd size integers. In this case using the header file "types.h" can help since it tells you the size of all built in types. You can then use preproccesor directives to choose the appropriate size for the situation. The answer to your question is that other languages do provide a "better" overall solution, if the performance of the compiled code is not critical. But where the need to translate high level language statements into as few and as fast a set of machine language instructions as possible is the goal, C offers a reasonable approach, and maybe even the "best solution" for that situation. -- Dave Scidmore, Heurikon Corp. dave.scidmore@heurikon.com
daves@ex.heurikon.com (Dave Scidmore) (05/02/91)
turk@Apple.COM (Ken "Turk" Turkowski) writes: >It is necessary to have 8, 16, and 32-bit data types, in order to be able >to read data from files. Bad practice!!!! This works fine if the one reading the data is always the same as the one writing it, but you are implying that these data sizes are important for having a machine read files written by another machine, then storing structures as binary images can result in severe problems. Byte ordering is a more fundamental problem than the size of types when trying to read and write binary images. The world of microcomputers is divided into two camps: those who store the least significant byte of a 16 or 32 bit quantity in the lowest memory location (as in Intel processors), and those which store the most significant byte in the lowest memory location (as in Motorola processors). Given the value 0x12345678 each stores 32 bit quantities as follows: Memory address LSB 0 1 2 3 0x78 0x56 0x34 0x12 LSB in lowest address (Intel convention) 0x12 0x34 0x56 0x78 MSB in lowest address (Motorola convention) From this you can see that if a big-endian processor writes a 32 bit int into memory a little endian processor will read it back backwards. The end result is the need to swap all bytes within 16 and 32 bit quantites. When reading structures from a file, this can only be done if you know the size of each component of the structure and swap it after reading. In general this is usualy sufficient reason not to store binary images of data in files unless you can assure that the machine reading the values will always follow the same size and byte ordering convention. >I would suggest NOT specifying a size for the int >data type; this is supposed to be the most efficient integral data type >for a particular machine and compiler. I agree. >A lot of programs rely on the fact that nearly all C implementations >have a 32-bit long int. The precident for non-32 bit ints predates the microprocessor and anyone who writes a supposedly "portable" program assuming long ints are 32 bits is creating a complex and difficult mess for the person who has to port the code to untangle. >I would suggest: > >short 16 bits >long 32 bits >long long 64 bits >int UNSPECIFIED >void * UNSPECIFIED I would suggest not making assumptions about the size of built in types when writing portable code. -- Dave Scidmore, Heurikon Corp. dave.scidmore@heurikon.com
phil@ux1.cso.uiuc.edu (Phil Howard KA9WGN) (05/02/91)
dlw@odi.com (Dan Weinreb) writes: >In article <1991May1.012242.26211@ux1.cso.uiuc.edu> phil@ux1.cso.uiuc.edu (Phil Howard KA9WGN) writes: > From: phil@ux1.cso.uiuc.edu (Phil Howard KA9WGN) > Date: 1 May 91 01:22:42 GMT > References: <168@shasta.Stanford.EDU> <1991Apr29.211937.10865@sco.COM> > Organization: University of Illinois at Urbana > IMHO, no code older than 8 years should be permitted to be ported >I see from the Organization field in your mail header that you're from >a university. I see from the domain in your return address you are from a commercial organization. SO............ -- /***************************************************************************\ / Phil Howard -- KA9WGN -- phil@ux1.cso.uiuc.edu | Guns don't aim guns at \ \ Lietuva laisva -- Brivu Latviju -- Eesti vabaks | people; CRIMINALS do!! / \***************************************************************************/
john@sco.COM (John R. MacMillan) (05/02/91)
|>4. Would it be better not to have a 32-bit data type and to make int |>be 64 bits? If so, how would 32- and 64- bit programs interact? | |It is necessary to have 8, 16, and 32-bit data types, in order to be able |to read data from files. It's not necessary, but it does make it easier. |I would suggest NOT specifying a size for the int |data type; this is supposed to be the most efficient integral data type |for a particular machine and compiler. | |[...] | |short 16 bits |long 32 bits |long long 64 bits |int UNSPECIFIED |void * UNSPECIFIED Problem with this is that I don't think sizeof(long) is allowed to be less than sizeof(int) which would constrain your ints to 32 bits.
phil@ux1.cso.uiuc.edu (Phil Howard KA9WGN) (05/02/91)
jerry@talos.npri.com (Jerry Gitomer) writes: > IMHO (now isn't that an arrogant phrase? :-) ) it is better to fix > up the offending programs now than to do it later. I say this > because I presume that salaries will continue to increase, which > will make it more expensive to fix things up later, and because > staff turnover leads to a decrease over time in knowledge of the > offending programs. Also, what about staff MORALE? I don't know about a lot of other programmers, but I for one would be much happier at the very least cleaning up old code and making it work right (or better yet rewriting it from scratch the way it SHOULD have been done in the first place) than perpetuationg bad designs of the past which translate into inefficiencies of the future. But if you are interested in getting things converted quickly, then just make TWO models of the compiler. You then assign a special flag name to make the compiler work in such a way that it will avoid breaking old code. Programs written AFTER the compiler is ready should be required to compile WITHOUT that flag. You could call the flag "-badcode". I think that might be a fair compromise between getting all the old bad code to work now under the new machine, while still promoting better programming practices for the present and future (and flagging examples of what NOT to do). -- /***************************************************************************\ / Phil Howard -- KA9WGN -- phil@ux1.cso.uiuc.edu | Guns don't aim guns at \ \ Lietuva laisva -- Brivu Latviju -- Eesti vabaks | people; CRIMINALS do!! / \***************************************************************************/
john@sco.COM (John R. MacMillan) (05/02/91)
|For how long should we keep porting code, especially BAD CODE? This sounds |a lot like school systems that keep moving failing students up each year |and we know what that results in. Whether or not it's a good idea, people will keep porting bad code as long as other people are willing to pay for it. Users are really buying Spiffo 6.3. They don't care how it's written; they just like it. So Monster Hardware, in an effort to boost sales, wants to be able to sell their boxes as a platform for running Spiffo 6.3. They don't care how it's written, they just want it. The core of Spiffo 6.3 is from Spiffo 1.0, and was written 10 years ago by 5 programmers who are now either VPs or no longer there, and who never considered it would have to run on an MH1800 where the chars are 11 bits and ints are 33. It happens. Honest. I suspect many of us know a Spiffo or two. |IMHO, no code older than 8 years should be permitted to be ported and if |it is found to be "bad" code then it must have been written more than 8 |years ago. The first part simply won't happen if there's demand, and I'm not sure I understand the second part.
cadsi@ccad.uiowa.edu (CADSI) (05/02/91)
From article <1991May01.172042.5214@buster.stafford.tx.us>, by rli@buster.stafford.tx.us (Buster Irby): > turk@Apple.COM (Ken "Turk" Turkowski) writes: > >>It is necessary to have 8, 16, and 32-bit data types, in order to be able >>to read data from files. I would suggest NOT specifying a size for the int >>data type; this is supposed to be the most efficient integral data type >>for a particular machine and compiler. > > You assume a lot about the data in the file. Is it stored in a specific > processor format (ala Intel vs Motorolla)? My experience has been that > binary data is not portable anyway. Binary isn't in general portable. However, using proper typedefs in a class one can move binary read/write classes from box to box. I think the solution the the whole issue of sizeof(whatever) is to simply assume nothing. Always typedef. It isn't that difficult, and code I've done this runs on things ranging from DOS machines to CRAY's COS (and UNICOS) without code (barring the typedef header files) changes. |----------------------------------------------------------------------------| |Tom Hite | The views expressed by me | |Manager, Product development | are mine, not necessarily | |CADSI (Computer Aided Design Software Inc. | the views of CADSI. | |----------------------------------------------------------------------------|
steve@taumet.com (Stephen Clamage) (05/02/91)
phil@ux1.cso.uiuc.edu (Phil Howard KA9WGN) writes: >But if you are interested in getting things converted quickly, then just make >TWO models of the compiler. You then assign a special flag name to make the >compiler work in such a way that it will avoid breaking old code. Some compilers already do this. For example, our compilers (available from Oregon Software) have a "compatibility" switch which allows compilation of old-style code, including old-style preprocessing. In this mode, ANSI features (including ANSI preprocessing and function prototypes) are still available, allowing gradual migration of programs from old-style to ANSI C. -- Steve Clamage, TauMetric Corp, steve@taumet.com
bright@nazgul.UUCP (Walter Bright) (05/03/91)
In article <12563@dog.ee.lbl.gov> torek@elf.ee.lbl.gov (Chris Torek) writes: /In article <168@shasta.Stanford.EDU> shap@shasta.Stanford.EDU (shap) writes: />How bad is it for sizeof(int) != sizeof(long). /It does cause problems---there is always software that makes invalid /assumptions---but typically long-vs-int problems, while rampant, are /also easily fixed. The most aggravating problem we have is it seems we (Zortech) are the only compiler for which: char signed char unsigned char are all distinct types! For example, char *p; signed char *ps; unsigned char *pu; p = pu; /* syntax error */ p = ps; /* syntax error */ It seems we are the only compiler that flags these as errors. A related example is: int i; short *ps; *ps = &i; /* syntax error, for 16 bit compilers too */ I think a lot of people are in for a surprise when they port to 32 bit compilers... :-)
jac@gandalf.llnl.gov (James A. Crotinger) (05/03/91)
cadsi@ccad.uiowa.edu (CADSI) writes: > to further these comments note that on a CRAY, a (char *) is a bit-packed > structure itself. In particular, the lower 48 bits are a pointer to > the word in memory where the character exists. The top 3 bits of the > 64-bit pointer are an index to the byte of the word of the actual > character. Thus, an (int *) cannot be conveniently cast to a (char *). > I hate it when that happens. And in Fortran, they also pack the string length into the word (only 32 bits are used for the word address). And the really awful thing is that this packing scheme is different on the X/Y-MP class machines than on the CRAY-2 machines. (I think the format for char *'s is different as well). Ack! As an aside, I wrote a nifty C++ class called FCD (Fortran character descriptor) which makes calling Fortran routines from C++ much cleaner. You prototype the fortran functions as taking FCD's rather than char *'s: void FORTRANFUNCTION( int &num, FCD string ); Then you just call it with your char *: main() { char * foo = "Hello"; FORTRANFUNCTION( 3, foo + 1 ); // Would break if this had been prototyped // to take a char *. } The FCD class has an inline constructor which converts the char * to an FCD. Much nicer than the hoops you have to jump through when using C. Unfortunately, the mechanism used by Sun (and other UNIXes?) for passing string lengths in Fortran is completely different. Rather than passing a structure containing the pointer and the length, they push the lengths onto the stack after pushing all the other args. This makes writing portable C++ code which interacts with Fortran libraries a pain. Jim -- ----------------------------------------------------------------------------- James A. Crotinger Lawrence Livermore Natl Lab // The above views jac@moonshine.llnl.gov P.O. Box 808; L-630 \\ // are mine and are not (415) 422-0259 Livermore CA 94550 \\/ necessarily those of LLNL
phil@ux1.cso.uiuc.edu (Phil Howard KA9WGN) (05/03/91)
steve@taumet.com (Stephen Clamage) writes: >Some compilers already do this. For example, our compilers (available from >Oregon Software) have a "compatibility" switch which allows compilation of >old-style code, including old-style preprocessing. In this mode, ANSI >features (including ANSI preprocessing and function prototypes) are still >available, allowing gradual migration of programs from old-style to ANSI C. Good. But is the rate of "gradual migration" catching up with, or falling behind, all the porting of old-style? From the sounds of some responses, it is falling behind fast. -- /***************************************************************************\ / Phil Howard -- KA9WGN -- phil@ux1.cso.uiuc.edu | Guns don't aim guns at \ \ Lietuva laisva -- Brivu Latviju -- Eesti vabaks | people; CRIMINALS do!! / \***************************************************************************/
shap@shasta.Stanford.EDU (shap) (05/03/91)
In article <13229@goofy.Apple.COM> turk@Apple.COM (Ken "Turk" Turkowski) writes: >I would suggest: > >short 16 bits >long 32 bits >long long 64 bits >int UNSPECIFIED >void * UNSPECIFIED > >This is patterned after ANSI floating-point extensions to accommodate >an extended format (i.e. "long double"). > >Another proposal would be to invent a new word, like "big", "large", >"whopper", "humongous", "giant", "extra", "super", "grand", "huge", >"jumbo", "broad", "vast", "wide", "fat", "hefty", etc. > >Whatever chaice is made, there should be ready extensions to 128 and 256 >bit integers, as well as 128 and 256-bit floating point numbers. Actually, that's what you did. The 'long long' data type does not conform to the ANSI standard. The advantage to the approach short 16 int 32 long 32 long long 64 Is that fewer datatypes change size (this approach leaves only pointers changing), and the code could conceivably have the same integer sizes in 32- and 64-bit mode. But isn't ANSI conformance a requirement?
shap@shasta.Stanford.EDU (shap) (05/03/91)
In article <4068@inews.intel.com> bhoughto@pima.intel.com (Blair P. Houghton) writes: >In article <168@shasta.Stanford.EDU> shap@shasta.Stanford.EDU (shap) writes: > >>2. If a trade-off has to be made between compliance and ease of >>porting, what's the better way to go? > >If you're compliant, you're portable. While I happen to agree with this sentiment, there is an argument that X hundred million lines of C code can't be wrong. The problem with theology is that it's not commercially viable. Reactions? Jonathan
shap@shasta.Stanford.EDU (shap) (05/03/91)
In article <1991May01.172042.5214@buster.stafford.tx.us> rli@buster.stafford.tx.us writes: >turk@Apple.COM (Ken "Turk" Turkowski) writes: > >>It is necessary to have 8, 16, and 32-bit data types, in order to be able >>to read data from files. I would suggest NOT specifying a size for the int >>data type; this is supposed to be the most efficient integral data type >>for a particular machine and compiler. > >You assume a lot about the data in the file. Is it stored in a specific >processor format (ala Intel vs Motorolla)? My experience has been that >binary data is not portable anyway.
ok@goanna.cs.rmit.oz.au (Richard A. O'Keefe) (05/03/91)
In article <1991May1.023356.8048@trl.oz.au>, peter@llama.trl.OZ.AU (Peter Richardson - NSSS) writes: > Hmmm. As I understand it. if you want to write truly portable code, you > should never make assumptions about sizeof any integral types. We have > a local header file on each machine type defining Byte, DoubleByte etc. > For example, on sun4: > > typedef unsigned char Byte; // always a single byte > typedef unsigned short DoubleByte; // always two bytes > typedef unsigned long QuadByte; // always four bytes > > If you want to use an int, use an int. If you want to use a 16 bit > quantity, use a DoubleByte. To port to new machines, just change the > header file. Purists may prefer "Octet" to "Byte". Sorry. You have just made a non-portable assumption, namely that there *is* an integral type which holds an octet and that there *is* an integral type which holds two octets, and so on. If you want "at least 8 bits", then use {,{,un}signed} char, and if you want "at least 16 bits", then use {,unsigned} short. The ANSI standard guarantees those. There is no need to introduce your own private names for them. If you want "exactly 8 bits" or "exactly 16 bits", you have no reason to expect that such types will exist. I am greatly disappointed that C++, having added so much to C, has not added something like int(Low,High) to the language, which would stand for the "most efficient" available integral type in which both Low and High were representable. The ANSI C committee were right not to add such a construct to C, because their charter was to standardise, not innovate. An anecdote which may be of value to people designing a C compiler for 64-bit machines: there was a UK company who built their own micro-coded machine, and wanted to put UNIX on it. Their C compiler initially had char=8, short=16, int=32, long=64 bits, sizeof (int) == sizeof (char*). They changed their compiler in a hurry, so that long=32 bits; it was less effort to do that than to fix all the BSD sources. It also turned out to have market value in that many of their customers had been just as sloppy with VAX code. sizeof (char) is fixed at 1. However, it should be quite easy to set up a compiler so that the user can specify (whether in an environment variable or in the command line) what sizes to use for short, int, long, and (if you want to imitate GCC) long long. Something like setenv CINTSIZES="16,32,32,64" # short,int,long,long long. The system header files would have to use the default types (call them __int, __short, and so on) so that only one set of system libraries would be needed, and this means that using CINTSIZES to set the sizes to something other than the defaults would make the compiler non-conforming. Make the defaults the best you can, but if you let people over-ride the defaults then the task of porting sloppy code will be eased. Other vendors have found the hard way that customers have sloppy code. -- Bad things happen periodically, and they're going to happen to somebody. Why not you? -- John Allen Paulos.
rli@buster.stafford.tx.us (Buster Irby) (05/03/91)
cadsi@ccad.uiowa.edu (CADSI) writes: >From article <1991May01.172042.5214@buster.stafford.tx.us>, by rli@buster.stafford.tx.us (Buster Irby): >> turk@Apple.COM (Ken "Turk" Turkowski) writes: >> >>>It is necessary to have 8, 16, and 32-bit data types, in order to be able >>>to read data from files. I would suggest NOT specifying a size for the int >> >> You assume a lot about the data in the file. Is it stored in a specific >> processor format (ala Intel vs Motorolla)? My experience has been that >> binary data is not portable anyway. >Binary isn't in general portable. However, using proper typedefs in >a class one can move binary read/write classes from box to box. I think >the solution the the whole issue of sizeof(whatever) is to simply assume >nothing. Always typedef. It isn't that difficult, and code I've done this >runs on things ranging from DOS machines to CRAY's COS (and UNICOS) without >code (barring the typedef header files) changes. What kind of typedef would you use to swap the high and low bytes in a 16 bit value? An Intel or BIG_ENDIAN machine stores the bytes in reverse order, while a Motorolla or LITTLE_ENDIAN machine stores the bytes in normal order (High to low). There is no way to fix this short of reading the file one byte at a time and stuffing them into the right place. The point I was trying to make is that reading and writing a data file has absolutely nothing to do with data types. As we have already seen, there are a lot of different machine types that support C, and as far as I know, all of them are capable of reading binary files, independent of data type differences. The only sane way to deal with this issue is to never assume anything about the SIZE or the ORDERING of data types, which is basically what the C standard says. It tells you that a long >= int >= short >= char. It says nothing about actual size or byte ordering within a data type. Another trap I ran accross recently is the ordering of bit fields. On AT&T 3B2 machines the first bit defined is the high order bit, but on Intel 386 machines the first bit defined is the low order bit. This means that anyone who attempts to write this data to a file and transport it to another platform is in for a surprise, they are not compatible. Again, the C standard says nothing about bit ordering, and in fact cautions you against making such assumptions.
cadsi@ccad.uiowa.edu (CADSI) (05/03/91)
From article <471@heurikon.heurikon.com>, by daves@ex.heurikon.com (Dave Scidmore): > warren@cbnewsh.att.com (warren.a.montgomery) writes: >>There are probably a lot of hidden assumptions in programs that >>sizeof(short)==2 and sizeof(long)==4 at this point, so any >>assignment of meanings on a 64 bit machine (unless you invent type >>"long long" for 64 bits and leave long and short at 32 and 16) >>will cause some pain. >> >>All this raises questions about C/C++'s philosophy of integer type >>specification, which no doubt dates from the days where all >>machines had only 2 and 4 byte integers. > > I doubt such a day ever existed. The early K&R book refered to machines > with 9 bit chars and 36 bit integers when describing the number of bits > in various quantities. > >>... How are things like this best >>expressed in C or C++? >>Do other languages provide better overall solutions? I add another fly to the ointment. What about bit sliced machines. At the low level, they really are 2 and 4 bit processors. At the high level (most human interaction levels) they are more like 32 and/or 64 bit machines. So, is this always a seperate issue from the compiler? I'm a little ignorant about the middle level of these machines, this is why I ask. |----------------------------------------------------------------------------| |Tom Hite | The views expressed by me | |Manager, Product development | are mine, not necessarily | |CADSI (Computer Aided Design Software Inc. | the views of CADSI. | |----------------------------------------------------------------------------|
sarima@tdatirv.UUCP (Stanley Friesen) (05/04/91)
In article <699@taumet.com> steve@taumet.com (Stephen Clamage) writes: >phil@ux1.cso.uiuc.edu (Phil Howard KA9WGN) writes: >Some compilers already do this. For example, our compilers (available from >Oregon Software) have a "compatibility" switch which allows compilation of >old-style code, including old-style preprocessing. So does the System V release 4 compiler. It has *three* switch setting. An 'old code' mode that compiles old style C but complains about non-ANSI code. A hybrid mode which mostly compiles ANSI C, but still accepts non- conflicting old-style stuff, and a *srict* ANSI mode, that enforces pure ANSI compliance. -- --------------- uunet!tdatirv!sarima (Stanley Friesen)
marc@dumbcat.sf.ca.us (Marco S Hyman) (05/05/91)
In article <226@tdatirv.UUCP> sarima@tdatirv.UUCP (Stanley Friesen) writes: > Binary communication between machines should use XDR *not* C structures. Agreed. (But please, not ASN.1/BER as someone else suggested :-) > First, C has this concept called bit fields, which can be of any size you > want - so if you *must* have a 16-bit quantity, use a 16-bit bit field. > (This also answers the previous objection - if you *must* be machine > dependent, at least make it stand out). And in article <230@tdatirv.UUCP> sarima@tdatirv.UUCP (Stanley Friesen) writes: > Remember if *bits* are important use bitfields The problem with using bit fields is that they might not be able to overlap the <allocation unit> boundary (ARM, pg 184-185: remember, we're talking C++ here) and that a programmer cant tell from looking at the code if the first field is placed in the high order bits or the low order bits. I suppose the former problem doesn't count because we want _smaller_ fields and since we are being machine dependent by using bit fields the last is not much of a problem either. These days I tend to think in terms of embedded processors with lots of low level peripheral device interface code. A '64-bit only' processor would not be an good match in this environment. -- // marc // home: marc@dumbcat.sf.ca.us pacbell!dumbcat!marc // work: marc@ascend.com uunet!aria!marc
cadsi@ccad.uiowa.edu (CADSI) (05/06/91)
From article <1991May03.120455.158@buster.stafford.tx.us>, by rli@buster.stafford.tx.us (Buster Irby): > cadsi@ccad.uiowa.edu (CADSI) writes: > >>Binary isn't in general portable. However, using proper typedefs in >>a class one can move binary read/write classes from box to box. I think >>the solution the the whole issue of sizeof(whatever) is to simply assume >>nothing. Always typedef. It isn't that difficult, and code I've done this >>runs on things ranging from DOS machines to CRAY's COS (and UNICOS) without >>code (barring the typedef header files) changes. > > What kind of typedef would you use to swap the high and low bytes > in a 16 bit value? An Intel or BIG_ENDIAN machine stores the > bytes in reverse order, while a Motorolla or LITTLE_ENDIAN > machine stores the bytes in normal order (High to low). There is > no way to fix this short of reading the file one byte at a time > and stuffing them into the right place. The point I was trying > to make is that reading and writing a data file has absolutely > nothing to do with data types. As we have already seen, there > are a lot of different machine types that support C, and as far > as I know, all of them are capable of reading binary files, > independent of data type differences. The big/little endian problem is handled via swab calls. AND, how do we know when to do this???? We just store the needed info in a header record. This header is read in block fashion and typedef'ed to the structure we need. from there, thats all we need to continue. The typedefs have to do with internal structures, NOT simple int, char and those type things, except for the BYTE type. Last but not least, you'll inevitably ask how we portably read that header. Well, we store a 'magic number' info and mess with things till the numbers are read correctly. Incidentally, that magic number also gives indications of code revision level and therefore what will and won't be possible. C'mon, this is not that difficult to comprehend. You want portable files??? Make 'em yourself. 'C' gives you all the toys you need to do this. [other stuff deleted - reference above] |----------------------------------------------------------------------------| |Tom Hite | The views expressed by me | |Manager, Product development | are mine, not necessarily | |CADSI (Computer Aided Design Software Inc. | the views of CADSI. | |----------------------------------------------------------------------------|
shap@shasta.Stanford.EDU (shap) (05/07/91)
In article <312@nazgul.UUCP> bright@nazgul.UUCP (Walter Bright) writes: > >The most aggravating problem we have is it seems we (Zortech) are the only >compiler for which: > char > signed char > unsigned char >are all distinct types! For example, One of us is misreading the standard. If it's me maybe someone can set me straight. My reading of the ANSI standard was that 'char' was identically equally to exactly one of 'unsigned char' or 'signed char', but that the choice was up to the compiler. Flagging suspect cases with a warning flag would be a useful feature, but doing it unconditionally is a pain in the butt. Have I misunderstood something in the standard? Jonathan
turk@Apple.COM (Ken Turkowski) (05/07/91)
rli@buster.stafford.tx.us (Buster Irby) writes: >An Intel or BIG_ENDIAN machine stores the >bytes in reverse order, while a Motorolla or LITTLE_ENDIAN >machine stores the bytes in normal order (High to low). You've got this perfectly reversed. Motorola is a BIG_ENDIAN machine, and Intel is a LITTLE_ENDIAN machine. Additionally, there is no such thing as "normal". -- Ken Turkowski @ Apple Computer, Inc., Cupertino, CA Internet: turk@apple.com Applelink: TURK UUCP: sun!apple!turk
turk@Apple.COM (Ken Turkowski) (05/07/91)
cadsi@ccad.uiowa.edu (CADSI) writes: >The big/little endian problem is handled via swab calls. >AND, how do we know when to do this???? We just store >the needed info in a header record. >This header is read in block fashion and typedef'ed to the structure we need. What type of header do you suggest? This should be able to record the ordering of shorts, longs, floats, and doubles, and might need to specify floating-point format. -- Ken Turkowski @ Apple Computer, Inc., Cupertino, CA Internet: turk@apple.com Applelink: TURK UUCP: sun!apple!turk
mike@taumet.com (Michael S. Ball) (05/07/91)
In article <184@shasta.Stanford.EDU> shap@shasta.Stanford.EDU (shap) writes: >In article <312@nazgul.UUCP> bright@nazgul.UUCP (Walter Bright) writes: >> >>The most aggravating problem we have is it seems we (Zortech) are the only >>compiler for which: >> char >> signed char >> unsigned char >>are all distinct types! For example, >Have I misunderstood something in the standard? You have. The standard states that char is a distinct type which has the same characteristics as either signed char or unsigned char. This appears to be a fairly late change, and earlier versions of the standard read as you assume. It's a bit strange, but makes very little difference in C. Carrying the same definition over to C++ can make things very strange indeed. The only solution given this definition is to make all characters which are really characters "char", and use signed char and unsigned char only for short arithmetic values. -- Michael S. Ball mike@taumet.com TauMetric Corporation (619)697-7607
chip@tct.com (Chip Salzenberg) (05/07/91)
According to bright@nazgul.UUCP (Walter Bright): >The most aggravating problem we have is it seems we (Zortech) are the only >compiler for which: > char > signed char > unsigned char >are all distinct types! G++ 1.39 knows that they're all distinct. It's free, too. -- Brand X Industries Sentient and Semi-Sentient Being Resources Department: Because Sometimes, "Human" Just Isn't Good Enough [tm] Chip Salzenberg <chip@tct.com>, <uunet!pdn!tct!chip>
daves@ex.heurikon.com (Dave Scidmore) (05/08/91)
>rli@buster.stafford.tx.us (Buster Irby) writes: >>An Intel or BIG_ENDIAN machine stores the >>bytes in reverse order, while a Motorolla or LITTLE_ENDIAN >>machine stores the bytes in normal order (High to low). In article <13357@goofy.Apple.COM> turk@Apple.COM (Ken Turkowski) writes: >You've got this perfectly reversed. Motorola is a BIG_ENDIAN machine, >and Intel is a LITTLE_ENDIAN machine. Additionally, there is no >such thing as "normal". Exactly. Both conventions have good points and bad points. The "normal" Motorolla convention starts to look a little less normal when dynamic bus sizing is required, in which case all byte data comes over the most significant data bus lines. In addition big endian machines have values that expand in size from the most significant location (i.e. two bytes values at location X have least significant bytes in a different location than four byte values at the same location). On the other hand the little endian convention looks odd when you do a dump of memory and try to find long words within a series of bytes. In the end you can make either convention look "normal" by how you draw the picture of it. For example which of these is normal for storing the value 0x12345678 ? Motorola: Location 0 1 2 3 Bytes 0x12 0x34 0x56 0x78 Intel: Location 3 2 1 0 Bytes 0x12 0x34 0x56 0x78 -- Dave Scidmore, Heurikon Corp. dave.scidmore@heurikon.com
daves@ex.heurikon.com (Dave Scidmore) (05/08/91)
In article <312@nazgul.UUCP> bright@nazgul.UUCP (Walter Bright) writes: >The most aggravating problem we have is it seems we (Zortech) are the only >compiler for which: > char > signed char > unsigned char >are all distinct types! For example, > char *p; > signed char *ps; > unsigned char *pu; > p = pu; /* syntax error */ > p = ps; /* syntax error */ >It seems we are the only compiler that flags these as errors. >A related example is: > int i; > short *ps; > *ps = &i; /* syntax error, for 16 bit compilers too */ >I think a lot of people are in for a surprise when they port to 32 bit >compilers... :-) A lot of compiler writers think they are doing you a favor by not reporting "trivial" errors. I would much rather have to say: char *p; signed char *ps; unsigned char *pu; p = (char*) pu; p = (char*) ps; than to have some subtle error result when I unknowingly perform such an assigment and some subtle side effect occurs. For example, if the above "unsigned char" pointer were to be used to read a buffer of characters, where the end of the buffer was indicated by the value 0x80, if written initialy on a nine bit per byte machine you would have no problem, but when ported to an eight bit per byte machine you will never find a "signed char" equal to 0x80 and so a bug will rear its ugly head. If the compiler warns that "p = pu" are incompatible types I can look at the statment and possibly remember that this won't work on an eight bit per byte machine. If it is what I intended all along, I *should* have used a cast so the next guy who looks at the code knows that the conversion is intentional. -- Dave Scidmore, Heurikon Corp. dave.scidmore@heurikon.com
cadsi@ccad.uiowa.edu (CADSI) (05/08/91)
From article <2826D9E7.407F@tct.com>, by chip@tct.com (Chip Salzenberg): > According to bright@nazgul.UUCP (Walter Bright): >>The most aggravating problem we have is it seems we (Zortech) are the only >>compiler for which: >> char >> signed char >> unsigned char >>are all distinct types! > > G++ 1.39 knows that they're all distinct. It's free, too. BUT, you're not supposed to make money on what you compile with G++, right? I thought I read that before. |----------------------------------------------------------------------------| |Tom Hite | The views expressed by me | |Manager, Product development | are mine, not necessarily | |CADSI (Computer Aided Design Software Inc. | the views of CADSI. | |----------------------------------------------------------------------------|
comeau@ditka.Chicago.COM (Greg Comeau) (05/09/91)
In article <312@nazgul.UUCP> bright@nazgul.UUCP (Walter Bright) writes: >char *p; signed char *ps; unsigned char *pu; >p = pu;/* syntax error */ p = ps; /* syntax error */ >It seems we [Zortech] are the only compiler that flags these as errors. I'm quite sure we (Comeau C++) do too. >A related example is: int i; short *ps; *ps = &i; We'd flag this too (even if you left off the *! ;-}). - Greg -- Comeau Computing, 91-34 120th Street, Richmond Hill, NY, 11418 Producers of Comeau C++ 2.1 Here:attmail.com!csanta!comeau / BIX:comeau / CIS:72331,3421 Voice:718-945-0009 / Fax:718-441-2310
comeau@ditka.Chicago.COM (Greg Comeau) (05/09/91)
In article <184@shasta.Stanford.EDU> shap@shasta.Stanford.EDU (shap) writes: >In article <312@nazgul.UUCP> bright@nazgul.UUCP (Walter Bright) writes: >>The most aggravating problem we have is it seems we (Zortech) are the only >>compiler for which: char signed char unsigned char >>are all distinct types! For example, >My reading of the ANSI standard was that 'char' was identically equally >to exactly one of 'unsigned char' or 'signed char', but that the choice >was up to the compiler. That may be so, but that doesn't say that it's not another type in and of itself even though we don't know its sign or which one "it's like". I any event ANSI C tells us "The three types char, signed char, and unsigned char are collectively call the ``character types''." while the ARM tells us "Plain char, signed char, and unsigned char, are three distinct types.". Remember also we've got "unsigned preserving" vs "value preserving" mess to contend with (of which I currently forget which C++ follows). - Greg -- Comeau Computing, 91-34 120th Street, Richmond Hill, NY, 11418 Producers of Comeau C++ 2.1 Here:attmail.com!csanta!comeau / BIX:comeau / CIS:72331,3421 Voice:718-945-0009 / Fax:718-441-2310
ok@goanna.cs.rmit.oz.au (Richard A. O'Keefe) (05/09/91)
In article <470@heurikon.heurikon.com>, daves@ex.heurikon.com (Dave Scidmore) writes: > I'm supprised nobody has mentioned that the real solution to this kind > of portability problem is for the original programmer to use the > definitions in "types.h" that tell you how big chars, shorts, ints, > and longs are. Why be surprised? I'm using an Encore Multimax running 4.3BSD, and on this machine there _isn't_ any types.h file. We have a copy of GCC, so we _have_ access to the ANSI file, but that's <limits.h>, not "types.h". -- Bad things happen periodically, and they're going to happen to somebody. Why not you? -- John Allen Paulos.
conor@lion.inmos.co.uk (Conor O'Neill) (05/09/91)
In article <179@shasta.Stanford.EDU> shap@shasta.Stanford.EDU (shap) writes: >While I happen to agree with this sentiment, there is an argument that X >hundred million lines of C code can't be wrong. The problem with >theology is that it's not commercially viable. Or did you mean "C hundred million lines of X code"... (Apparently X even has such nasties buried inside it as expecting that successive calls to malloc have higher addresses, forcing the heap to grow upwards.) (So I'm informed) --- Conor O'Neill, Software Group, INMOS Ltd., UK. UK: conor@inmos.co.uk US: conor@inmos.com "It's state-of-the-art" "But it doesn't work!" "That is the state-of-the-art".
chip@tct.com (Chip Salzenberg) (05/09/91)
According to cadsi@ccad.uiowa.edu (CADSI): >From article <2826D9E7.407F@tct.com>, by chip@tct.com (Chip Salzenberg): >> G++ 1.39 ... is free, too. > >BUT, you're not supposed to make money on what you compile with G++, >right? I thought I read that before. Wrong. You can make money off a program compiled with G++. In fact, we have our very first C++ project in beta test right now, and it's all compiled with G++. The trick is that you can't distribute a program containing GNU code (like the GNU C++ library "libg++") unless you also distribute source code to the whole program linked therewith. We avoid this problem by avoiding libg++. A new version of the GNU public license may soon make a special case of libraries, by requiring distribution of library source code, but not the source code of the program(s) linked with the library. Stay tuned in gcc.announce and gnu.misc.discuss. -- Brand X Industries Sentient and Semi-Sentient Being Resources Department: Because Sometimes, "Human" Just Isn't Good Enough [tm] Chip Salzenberg <chip@tct.com>, <uunet!pdn!tct!chip>
david@ap542.uucp (05/15/91)
-cadsi@ccad.uiowa.edu (CADSI) writes: ->by rli@buster.stafford.tx.us (Buster Irby): ->> cadsi@ccad.uiowa.edu (CADSI) writes: ->> ->>>Binary isn't in general portable. However, using proper typedefs in ->>>a class one can move binary read/write classes from box to box. ->> ->> What kind of typedef would you use to swap the high and low bytes ->> in a 16 bit value? An Intel or BIG_ENDIAN machine stores the ->> bytes in reverse order, while a Motorolla or LITTLE_ENDIAN ->> machine stores the bytes in normal order (High to low). There is ->> no way to fix this short of reading the file one byte at a time ->> and stuffing them into the right place. -> ->The big/little endian problem is handled via swab calls. ->AND, how do we know when to do this???? We just store ->the needed info in a header record. NO, NO, NO! The way to do this is to use XDR. **========================================================================** David E. Smyth david%ap542@ztivax.siemens.com <- I can get your mail, but our mailer is broken. But I can post. You figure... **========================================================================**
ray@philmtl.philips.ca (Ray Dunn) (05/16/91)
In referenced article, bhoughto@pima.intel.com (Blair P. Houghton) writes: >>2. If a trade-off has to be made between compliance and ease of >>porting, what's the better way to go? > >If you're compliant, you're portable. This is like saying if the syntax is correct then the semantics must be too although, indeed, there is no need to trade compliance for portability. There are dangers clearly visible though. All you can say is that your compliant program has an excellent chance of compiling on another system running a compliant compiler, not that it will necessarily work correctly with the new parameters plugged in. You only know a program is portable *after* you've tested it on another system. How many do that during the initial development cycle? Porting is not an issue that goes away by writing compliant code - it may in fact *hide* some of the problems. If I wanted to be controversial, I might say that 'C's supposed "portability" is a loaded cannon. Bugs caused by transferring a piece of software to another system will continue to exist, even in compliant software. Prior to "portable" 'C', porting problems were *expected*, visible, and handled accordingly. Will developers still assume these bugs to be likely, and handle verification accordingly, or will they be lulled by "it compiled first time" into thinking that the portability issue has been taken into account up front, and treat it with less attention than it deserves? -- Ray Dunn. | UUCP: ray@philmtl.philips.ca Philips Electronics Ltd. | ..!{uunet|philapd|philabs}!philmtl!ray 600 Dr Frederik Philips Blvd | TEL : (514) 744-8987 (Phonemail) St Laurent. Quebec. H4M 2S9 | FAX : (514) 744-9550 TLX: 05-824090
jeh@cmkrnl.uucp (05/16/91)
In article <521@heurikon.heurikon.com>, daves@ex.heurikon.com (Dave Scidmore) writes: > [...] > On the other hand the little > endian convention looks odd when you do a dump of memory and try to find long > words within a series of bytes. Yup. But this can be solved. The VAX is a little-endian machine, and VMS utilities address [ahem] this problem by always showing hex contents with increasing addresses going from right to left across the page. Since significance of the bytes (actually the nibbles) increases with increasing addresses, this looks perfectly correct... the most significant nibble goes on the left, just the way you'd "naturally" write it. For example, the value 1 stored in 32 bits gets displayed as 00000001. If you get a hex-plus-Ascii dump, such as is produced by DUMP (for files) or ANALYZE/SYSTEM (lets you look at live memory), the hex goes from right to left, and the ascii from left to right, like this: SDA> ex 200;60 0130011A 0120011B 0130011E 0110011F ......0... ...0. 00000200 01200107 02300510 04310216 04210218 ..!...1...0... . 00000210 01100103 01100104 01200105 01200106 .. ... ......... 00000220 44412107 01100100 01100101 01100102 .............!AD 00000230 4B202020 20444121 44412106 42582321 !#XB.!AD!AD K 00000240 00524553 55525055 53434558 454E5245 ERNEXECSUPRUSER. 00000250 In the last row, the string "EXEC" is at address 253, and the last byte on the line, 25F, contains hex 00. In the first row, the word (16 bits) at location 204 contains hex value 11E; if you address the same location as a longword, you get the value 0130011E. This looks completely bizarre at first, but once you get used to it (a few minutes or so for most folks) it makes perfect sense. The VAX is consistent in bit numbering too: The least significant bit of a byte is called bit 0, and when you draw bit maps of bytes or larger items, you always put the lsb on the right. --- Jamie Hanrahan, Kernel Mode Consulting, San Diego CA Chair, VMS Internals Working Group, U.S. DECUS VAX Systems SIG Internet: jeh@dcs.simpact.com, hanrahan@eisner.decus.org, or jeh@crash.cts.com Uucp: ...{crash,scubed,decwrl}!simpact!cmkrnl!jeh
augliere@bbn.com (Reed Augliere) (05/18/91)
I've just installed the Oregon C++ compiler on a VaxStation 3100 running VMS 5-3.1 and am trying to get it to work with MOTIF 1.1 (DEC MOTIF Developer's Kit). I'm getting all kinds of compile errors which are apparently a consequence of conflicts with with C language constants in certain VMS header files (like "new" and "class") and with what is apparently a VMS-specific datatype: "externalref". Has anybody tried to use the Oregon C++ compiler using MOTIF on VMS? If so, have you encountered this problem and figured out a solution? Any help will be greatly appreciated. Reed Augliere raugliere@bbn.coM
bhoughto@pima.intel.com (Blair P. Houghton) (05/18/91)
In article <1991May15.190016.21817@philmtl.philips.ca> ray@philmtl.philips.ca (Ray Dunn) writes: >In referenced article, bhoughto@pima.intel.com (Blair P. Houghton) writes: >>If you're compliant, you're portable. > >You only know a program is portable *after* you've tested it on another >system. How many do that during the initial development cycle? Well, I do, several times, to the point of working for a while on one platform, moving to another, testing, working there for a while, moving to a third, and so on. It helps to aim for three targets. >If I wanted to be controversial, I might say that 'C's supposed >"portability" is a loaded cannon. Bugs caused by transferring a piece of >software to another system will continue to exist, even in compliant >software. Prior to "portable" 'C', porting problems were *expected*, >visible, and handled accordingly. Now they're bugs in the compiler, not just "issues of implementation." If you're using any C construct that produces different behavior on disparate, conforming implementations, then either one of those implementations is not conforming or you are not using ANSI C, but rather have used some sort of extension or relied on some sort of unspecified behavior, and therefore your program is not compliant. >Will developers still assume these bugs to be likely, and handle >verification accordingly, or will they be lulled by "it compiled first >time" into thinking that the portability issue has been taken into account >up front, and treat it with less attention than it deserves? Your question is all but naive. I still get valid enhancement requests on code that's several years old, which means that I failed to design it to suit the needs of my customer, which means it's buggy. Routines that have been compiled and/or run thousands of times in real-world situations come up wanting. Nobody sane assumes that anything is right the first time (though one may determine that the probability of failure is low enough to make an immediate release feasible). --Blair "I'm going to put all of this on video and hawk it on cable teevee in the middle of the night while wearing pilled polyester and smiling a lot."
ray@philmtl.philips.ca (Ray Dunn) (05/21/91)
In referenced article, bhoughto@pima.intel.com (Blair P. Houghton) writes: >In referenced article, ray@philmtl.philips.ca (Ray Dunn) writes: >>Prior to "portable" 'C', porting problems were *expected*, >>visible, and handled accordingly. > >Now they're bugs in the compiler, not just "issues of >implementation." No - now they're "issues of *system dependancies*". >>Will developers still assume these bugs to be likely, and handle >>verification accordingly, or will they be lulled by "it compiled first >>time" into thinking that the portability issue has been taken into account >>up front, and treat it with less attention than it deserves? > >Your question is all but naive. Only if you ignore the fact, which you seem to do, that many of the issues of portability in the real world are created by differences in system hardware, operating systems and file management facilities. This is true for nearly all software for example which has a tightly coupled user interface, or which is forced to process system specific non-ascii-stream data files, or to interface with multi-tasking facilities. Even differencies in Floating Point handling can create major pains-in-the-neck. There's more to portability than 'C' conformity. -- Ray Dunn. | UUCP: ray@philmtl.philips.ca Philips Electronics Ltd. | ..!{uunet|philapd|philabs}!philmtl!ray 600 Dr Frederik Philips Blvd | TEL : (514) 744-8987 (Phonemail) St Laurent. Quebec. H4M 2S9 | FAX : (514) 744-9550 TLX: 05-824090 -- Ray Dunn. | UUCP: ray@philmtl.philips.ca Philips Electronics Ltd. | ..!{uunet|philapd|philabs}!philmtl!ray 600 Dr Frederik Philips Blvd | TEL : (514) 744-8987 (Phonemail) St Laurent. Quebec. H4M 2S9 | FAX : (514) 744-9550 TLX: 05-824090