am@cl.cam.ac.uk (Alan Mycroft) (08/02/88)
The following two points appear to be oddities in ANSI 3rd public review spec. 1. The function int f() { int x; char y; return sizeof(x)==sizeof(y); } seems required to return 1!!!! Reasoning: 3.2.1.1 says: "A char ... may be used in an expression wherever an int may be used ... the value is converted to an int." sizeof(.) is certainly a context in which an int may be used and so sizeof(<char variable>)==sizeof(int). Note that sizeof(char) probably differs from sizeof(<char variable>). I observe that the spec goes to some great trouble to specify where an array or function is converted to a pointer (3.2.2.1) whereas the notionally(?) identical contexts where char is converted to int suffers from sloppy drafting. (Convince me I'm wrong!) 2. 4.12.1: "[In <time.h>] 'struct tm' ... shall contain *at least* the following members... int tm_sec; ...". However, it would seem that an *implementation* would be non-conforming if it contained more members: Suppose an implementer added a field 'foo' (say) to struct tm. Then the program #define foo @@@@@whizz!!! #include <time.h> would not compile (assuming <time.h> was textual). Hence the implementor can only add names in the reserved space of _A-Z or __A-Za-z0-9_. This same remark obtains for views like: >In <7351@cit-vax.Caltech.Edu> beckenba@cit-vax.UUCP (Joe Beckenbach) writes: >> Showing just the members seems to indicate to me that the members >>listed are definitely there, but other members might be as well which >>should really not be tampered with. This is simply information-hiding >>which might be better done implemented in software than by lack of reference >>in the documentation.
karl@haddock.ISC.COM (Karl Heuer) (08/04/88)
In article <253@gannet.cl.cam.ac.uk> am@cl.cam.ac.uk (Alan Mycroft) writes: >2. 4.12.1: "[In <time.h>] 'struct tm' ... shall contain *at least* > the following members... int tm_sec; ...". > However, it would seem that an *implementation* would be non-conforming > if it contained more members: ... Well, a conforming implementation could certainly add members in the reserved namespace (leading underscore), and it could provide convenient access to them via a macro "#define tm_usec __tm_extended_usec" which is only defined if the user has enabled the extensions ("#include <extensions.h>" or whatever). This is the same sort of situation that the implementor must face when providing non-ANSI functions like read(). Karl W. Z. Heuer (ima!haddock!karl or karl@haddock.isc.com), The Walking Lint
guy@gorodish.Sun.COM (Guy Harris) (08/05/88)
> Well, a conforming implementation could certainly add members in the reserved > namespace (leading underscore), and it could provide convenient access to > them via a macro "#define tm_usec __tm_extended_usec" which is only defined > if the user has enabled the extensions ("#include <extensions.h>" or > whatever). Or, alternatively, if your implementation has some way of distinguishing "no-extensions" mode from "extensions" mode with some #ifdef at compile time, you could do: struct tm { int tm_sec; int tm_min; int tm_hour; int tm_mday; int tm_mon; int tm_year; int tm_wday; int tm_yday; int tm_isdst; #ifdef __EXTENSIONS__ char *tm_zone; long tm_gmtoff; #else char *__tm_filler_1; long __tm_filler_2; #endif }; Unfortunately, there's no way to have unnamed fillers that aren't bit-fields, so there's no way I can see of doing this without polluting your namespace with ugly, although probably harmless "__tm_filler_N" names. If you could do this, I'd prefer it; struct tm { ... #ifdef __EXTENSIONS__ char *tm_zone; long tm_gmtoff; #else char *; int; #endif }; anyone? :-)
guy@gorodish.Sun.COM (Guy Harris) (08/05/88)
> Unfortunately, there's no way to have unnamed fillers that aren't bit-fields, > so there's no way I can see of doing this without polluting your namespace... Make that "no clean, portable way I can see of doing this...". Yes, you can, in any given implementation, stick in an unnamed bit field that happens to be the same size as the structure member that you're trying to render anonymous, but you'd have to tweak the size of the bit field in different implementations.
karl@haddock.ISC.COM (Karl Heuer) (08/09/88)
[karl@haddock (Karl Heuer) writes that "#define tm_usec __tm_extended_usec" as
a conditionally defined macro would do the job]
[guy@gorodish.Sun.COM (Guy Harris) notes the alternative solution
struct tm { ...
#ifdef __EXTENSIONS__
long tm_usec;
#else
long __tm_filler_1;
#endif
};
but says that this pollutes the namespace with "__tm_filler_N" names.]
Yes, but it's polluting the *implemention's* namespace, not the user's. The
implementor need only check that the pattern "__tm_*" is not on the (finite)
list of patterns already in use by the implementation. From the user's
viewpoint, this extension (either yours or mine) is harmless.
Karl W. Z. Heuer (ima!haddock!karl or karl@haddock.isc.com), The Walking Lint