Thread View: comp.std.c
2 messages
2 total messages
Started by Dave Kinchlea
Fri, 12 Apr 1996 00:48
offsetof() and `address constant expression': LONG
Author: Dave Kinchlea
Date: Fri, 12 Apr 1996 00:48
Date: Fri, 12 Apr 1996 00:48
132 lines
6629 bytes
6629 bytes
I think the excellent reply included below from Roger Glover of CRI (from an original thread in comp.unix.cray) says just about everything, but for a little more context. I am porting pdksh5.2.4 to UNICOS and I came across a compiler error that I thought I had attributed to the following (mis-)defined macro in stddef.h: #if _RELEASE < 3 #define offsetof(t, memb) ((size_t)__INTADDR__(&(((t *)0)->memb))) #else #ifndef __cplusplus #define offsetof(_TYPE, _MEMBER) _Offsetof(_TYPE, _MEMBER) #else #define offsetof(ty,mem) ((size_t)((char *)&(((ty*)0)->mem) - (char *) 0)) #endif #endif I conjectured that the #ifndef __cplusplus was meant to be #ifdef (the compiler version is 4.0), that is the macro that I ended up redefining to get the code to compile, and appearently work. Roger makes an excellent case to support the compiler errors, I think everything hinges on the exact definition of address constant expression. Plauger says: An address constant expression specifies a value that has a pointer type and that the translator or target environment can determine prior to program startup. Therefore, the epxression must not cause side effects. ... Seems pretty clear that the use below does not fit this description but I would like some confirmation before I send this back to the author. If it matters, that call is out of an alloc() routine. ICELLS is a macro (100) and cells is an integer. I think I will let Roger take over ... On Thu, 11 Apr 1996, Roger Glover wrote: > Dave: > > I took a spare moment to look a this again. Your code line was: > > :> bp = (Block*) malloc(offsetof(Block, cell[ICELLS + cells])); > > Your error messages were: > > :> cc-544 cc: ERROR File = alloc.c, Line = 92 > :> The token "cells" is not valid in a constant expression in this context. > :> cc-424 cc: ERROR File = alloc.c, Line = 92 > :> The array subscript expression is not a positive integral expression. > :> cc-477 cc: ERROR File = alloc.c, Line = 92 > :> An expression is terminated with ")" instead of ";". > > I used the UNICOS "explain" command to look at these messages in more > detail. Here is what I got for the first message: > > $ explain cc-544 > > CC_ERROR: The token "token" is not valid in a constant expression in this > context. > > The specified token, while valid within some constant expressions, is not > valid within a constant expression used to specify the size of a bit field > member, the value of an enumeration constant, or the value of a case > constant. Remove the indicated operator from the constant expression. > > Not particularly instructive, but the second message cleared things > up a bit: > > $ explain cc-424 > > CC_ERROR: The array subscript expression is not a positive integral > expression. > > The expression that specifies the subscript of an array within an offsetof > macro must be an integral constant expression that has a value greater than > ^^^^^^^^ [[ my emphasis - rg ]] > zero. Either the subscript specified is not an integral constant expression > or its value is less than or equal to 0. > > It clear that the subscript expression (ICELLS + cells) is not > constant because the variable "cells" is not constant. The > straightforward macro that you are suggesting is the correct one: > > #define offsetof(ty,mem) ((size_t)((char *)&(((ty*)0)->mem) - (char *) 0)) > > does not do any integrity checking of the second argument, whereas > the one you are suggesting is wrong: > > #define offsetof(_TYPE, _MEMBER) _Offsetof(_TYPE, _MEMBER) > > apparently does perform integrity checking. > > The question remains: Is the integrity check correct? Well, the fact > that the error message is cc-424 (indicating the C compiler rather > ^^ > than the C++ compiler) shows me that the integrity check is > intentionally associated with C rather than C++. So I turned to the > standards (more or less). Plauger and Brodie's "Standard C Quick > Reference" (ISBN: 1-55615-158-6), which is a concise interpretation > of the ANSI/ISO C standard, says the following about the "offsetof" > macro: > offsetof > #define offsetof(s-type,mbr) <size_t constant expression> > The macro yields the offset in bytes of member mbr from the beginning > of structure type s-type, where for X of type s-type, &X.mbr is an > address constant expression. > ^^^^^^^^ > > Well let's break that down a bit. &X.mbr must be constant, so that > implies that both X must represent fixed locations and mbr must > represent a fixed offset from that location. In your case, mbr is > "cell[ICELLS + cells]", which does not represent a fixed offset, > since "cells" can vary. > > Now one more question remains: Why doesn't C++ have the same > integrity check? I don't know. As far as I can tell, the C++ draft > standard subsumes stddef.h, "as is" from ANSI/ISO C. Perhaps their > is an implementation dependency related to our C++ compiler, but I > can't tell. > > In any case, I do not think the behavior you described is a bug. > > ----------------------------------------------- Roger Glover > XXXX\ \ / \ /XXX \ / \ X \ /\\\ X///X /\\\ Cray Research, Inc. > / \ / \/ /\ / \ / \X /\ X \ / \ X\ \ X DISCLAIMER HAIKU: > //X/ X\\\X //X/ X \ X X\\ / \ X/X \ X \\\ C R I may not > / \ X///X / \/ X//XX X \ / \ X \\ X \ Share these opinions with me > / \ X X /\\\/ X X X///X /XXX/ X///X /XXX/ This is not my fault > ----------------------------------------------- http://www.cray.com/education kinch <finger kinch@julian.uwo.ca> for PGP key(s) email:kinch@julian.uwo.ca web:http://www.heartlab.rri.uwo.ca/kinch/ Unix PGP Key fingerprint = 6F 36 6F 9D 79 16 DF 40 2B EC 18 5B 5C 6D 03 6F Home PGP Key fingerprint = 28 20 0E DF 27 17 80 C5 5D 04 8E 1B D0 9A A6 4C
Re: offsetof() and `address constant expression': LONG
Author: Norman Diamond
Date: Sat, 13 Apr 1996 01:32
Date: Sat, 13 Apr 1996 01:32
31 lines
2037 bytes
2037 bytes
In article <4kk988$rt2@falcon.ccs.uwo.ca>, Dave Kinchlea <kinch@julian.uwo.ca> writes 100 lines more than this: >Seems pretty clear that the use below does not fit this description >[arguments to offsetof] but I would like some confirmation before I >send this back to the author. [...] >ICELLS is a macro (100) and cells is an integer. Sounds like you already got it: >On Thu, 11 Apr 1996, Roger Glover wrote: >>> bp = (Block*) malloc(offsetof(Block, cell[ICELLS + cells])); >> Plauger and Brodie's "Standard C Quick Reference" [...] says [...] >> #define offsetof(s-type,mbr) <size_t constant expression> >> The macro yields the offset in bytes of member mbr from the beginning >> of structure type s-type, where for X of type s-type, &X.mbr is an >> address constant expression. Looks like Plauger and Brodie forgot to say *static* X of type s-type. However, they got the rest of it right. >> Well let's break that down a bit. &X.mbr must be constant, Yes. And the standard's section on constant expressions, paragraph on address constants, says: "[...] but the value of an object shall not be accessed by one of these operators." So the + operator which accesses the value of cells does not yield a constant expression. -- << If this were the company's opinion, I would not be allowed to post it. >> "I paid money for this car, I pay taxes for vehicle registration and a driver's license, so I can drive in any lane I want, and no innocent victim gets to call the cops just 'cause the lane's not goin' the same direction as me" - J Spammer
Thread Navigation
This is a paginated view of messages in the thread with full content displayed inline.
Messages are displayed in chronological order, with the original post highlighted in green.
Use pagination controls to navigate through all messages in large threads.
Back to All Threads