padpowell@wateng.UUCP (PAD Powell[Admin]) (08/30/83)
I hit a really odd bug the other day, and just thought I would pass it along to the C compiler community. Suppose that I have a structure, with fields of various widths, and my machine architecture demands that I have addresses on various alingments. For the sake of argument, char is any alignment, short is mod 2 (2 chars), int is mod 4, and float is mod 16. The structure I defined was: struct test { char c; short s; int i; float f; } I pass a struct value to a subroutine (I mean function), and also have a local variable. test_funct( s ) struct test s; { struct test t; /* bunch of assignments */ return( s == t) } Now in the "bunch of assignments, I set the various fields of t to the same values as the fields of s. According to various persons, in the extended version of C, passing a structure by "value" is permitted. Also, comparison and assignment of structures is permitted. However, this code fails with several compilers, for the funny reason that the comparison fails. When the "t" variable is allocated on the stack, the "cracks" or unused space in the structure are set to garbage. The code usually generated for comparison will compare the entire structure in the most effective manner, usually using a block comparison instruction. This is one of the most annoying of all types of language "flakes", which has been called by various people the "semantic gap", or the problems of mapping a language to a machine architecture. I suppose that there is a way of fixing this. 1. Extend the definition of the language so that all local variables are initialized to 0. Pro: it solves the problem. Con: THE OVERHEAD!!!! Function calls are bad enough, and now you want to make them worse? 2. Extend the definition so that all "cracks" in structures are set to 0. Pro: it solves the problem. Con: overhead is still substantial. Reduces the cost, but is still pretty bad. 3. Write a big BOLDFACED, BOXED, and perhaps dayglow orange warning in the language definition manual, and indicate that keeping around a static or global variable, set to all 0's, and assignment of it to a structure variable will guarantee that the "cracks" are filled with 0's. Pro: it probably will solve the problem. Con: Manuals are never read. The problem still exists, and people will still hit it. This will lead to net.lang.c getting flames about once every 6 months from the next group of people to hit this... Also, assignment of structure to structure must be defined so that the crack filling is guaranteed to work. Patrick Powell, U. Waterloo, Waterloo, Ont. ...watmath!wateng!padpowell
ark@rabbit.UUCP (09/01/83)
wateng!padpowell complains that structure comparison doesn't do the "right think" with the padding between elements. Now you know why structure comparison isn't part of the language. The only things you can do with a structure are: take its address, select an element of it, pass it to a function, return it as a value, and assign it to another (identical) structure.
guy@rlgvax.UUCP (Guy Harris) (09/02/83)
According to "Recent Changes to C", distributed both with V7 and System III UNIX: "Structures may be assigned, passed as arguments to functions, and returned by functions. ... Other plausible operators, such as equality comparison, have not been implemented." From a document distributed in machine-readable form only(!) with System III: Structure assignment has been added to the C language to simplify both the source and object code associated with transferring the value of one structure instance to another and to allow functions to return aggregate values when invoked. Since many processors now contain some type of `move block' instruction, structure assignment will permit more efficient use of many machines. It also makes source programs more readable. Structures may be assigned, passed as arguments to functions, and returned by functions. The types of structure operands taking part must be the same. Other plausible operators, such as equality comparison and structure casts, are not being implemented due to the difficulties associated with "holes" in structures caused by alignment restrictions. So the problem with structure comparison is known; in fact, that's why none of the C compilers I've encountered implement it. Guy Harris {seismo,mcnc,we13,brl-bmd,allegra}!rlgvax!guy
alan@allegra.UUCP (09/02/83)
Gee, if every compiler writer and his uncle adds his favorite extension to the language -- structure comparison, string manipulation, or whatever -- C can become as plauged by portability problems as Pascal is. What fun! Alan Driscoll Bell Labs, Murray Hill
mrm@datagen.UUCP (09/02/83)
I was under the opinion that structure comparisions were forbidden (as well as structure casts) because of just the problem you mention. Michael Meissner Data General Corporation ...(decvax!ittvax, allegra)!datagen!mrm
decot@cwruecmp.UUCP (Dave Decot) (09/14/83)
Seems to me that another solution to the "holes" problem of structure comparison is somewhat clear: Permit comparison of two structures of the same tag or typedef for [in]equality only. If the structure template involved contains no holes, compare the structures using a block-compare instruction (if available). If there ARE holes, the result is the && conjunction [|| disjunction] of comparisons for [in]equality of constituent blocks that have no holes. Thus, those areas of the structures that should be equal are compared, and those that are "holes" are ignored, and the code thus generated can be no worse than that generated by the poor programmer who has to code this comparison by "hand". No? Replies are encouraged. Dave Decot ..!decvax!cwruecmp!decot
dmmartindale@watcgl.UUCP (Dave Martindale) (09/14/83)
From: decot@cwruecmp.UUCP (Dave Decot) Newsgroups: net.lang.c Seems to me that another solution to the "holes" problem of structure comparison is somewhat clear: Permit comparison of two structures of the same tag or typedef for [in]equality only. If the structure template involved contains no holes, compare the structures using a block-compare instruction (if available). If there ARE holes, the result is the && conjunction [|| disjunction] of comparisons for [in]equality of constituent blocks that have no holes. Thus, those areas of the structures that should be equal are compared, and those that are "holes" are ignored, and the code thus generated can be no worse than that generated by the poor programmer who has to code this comparison by "hand". This would prevent you from storing C-style strings in these structures. Arrays which are used as arrays must, of course, have all elements compared. But the semantics of comparing a conventional C string call for comparing bytes only until a null byte is reached; the contents of the bytes in the char array following the null byte are often garbage from a longer string which previously occupied that memory. If someone were hand-coding the comparison of two structures, they would use either strcmp (or strncmp) or a block compare of some sort depending on their knowledge of whether each char array really contained a string or not. The compiler cannot know. To have byte-by-byte comparison work properly, you must switch to string-copying routines which always ensure that the destination is padded with some well-defined pattern (probably nulls) to its end.
edler@cmcl2.UUCP (09/14/83)
#R:wateng:-27500:cmcl2:15400004:000:711 cmcl2!edler Sep 14 16:54:00 1983 The following suggestion has been made: Permit comparison of two structures of the same tag or typedef for [in]equality only. If the structure template involved contains no holes, compare the structures using a block-compare instruction (if available). If there ARE holes, the result is the && conjunction [|| disjunction] of comparisons for [in]equality of constituent blocks that have no holes. This won't work for structures containing unions of different-sized components. For example, I don't see how any C compiler can compare two instances of the following structure: struct a { int b; union { char c; long d; } e; }; Jan Edler cmcl2!edler (New York University) edler@nyu
ka@spanky.UUCP (Kenneth Almquist) (09/18/83)
Before we discuss how to implement structure comparison, we should consider whether structure comparison should be implemented at all. I don't think it should. I think that the number of programs that could benefit from a structure comparison operator is quite small. (My opinion, anyone want to come up with a list of cases where structure comparison would be useful?) As a result, some compiler implementers will probably not bother with structure comparison and so that people will tend to avoid the feature to ensure portability even if they do have a use for it. In short, I expect structure comparison to become known as a feature that flopped if it is added to C. Kenneth Almquist