cspw.quagga@p0.f4.n494.z5.fidonet.org (cspw quagga) (06/02/90)
Some questions about ANSI C. 1) Did the 'offsetof' macro make it into the finals? I notice it is missing in TurboC 2.0, but present in a couple of other compilers that also claim ANSI compatibility. 2) I want to find out how many elements are in my initialized arrays. char s[][5] = { "sun", "mon", "tues" ... }; #define num_elems(array) (sizeof(array)/(&array[1]-&array[0])) Will this work, even in the presence of pad bytes? (ie will the sizeof the total structure always be an exact multiple of the size of the padded individual elements, or is the compiler allowed to insert different padding sizes at the beginning or end?). Is there an easier way that works in all cases? 3) I'd like to check at that two arrays have the same number of initializers. int a[] = { 0,1,2,3,4, ... }; char s[][5] = { "sun", "mon", "tues" ... }; I'd like this check at compile time, so I'd like to be able to write #if (num_elems(a) - num_elems(s)) cause a deliberate compilation error #endif But, uh-huhm, the 'sizeof' and the pointer arithmetic is not permitted at pre-processing time. Any way to do this nicely? Pete -- EP Wentworth - Dept. of Computer Science - Rhodes University - Grahamstown. Internet: cspw.quagga@f4.n494.z5.fidonet.org Uninet: cspw@quagga uucp: ..uunet!m2xenix!quagga!cspw -- uucp: uunet!m2xenix!puddle!5!494!4.0!cspw.quagga Internet: cspw.quagga@p0.f4.n494.z5.fidonet.org
steve@taumet.COM (Stephen Clamage) (06/04/90)
In article <6644.26663D46@puddle.fidonet.org> cspw.quagga@p0.f4.n494.z5.fidonet.org (EP Wentworth) writes: >1) Did the 'offsetof' macro make it into the finals? I notice Yes. > it is missing in TurboC 2.0, but present in a couple of other > compilers that also claim ANSI compatibility. It is in Turbo C++ 1.0 (which is also a full ANSI C compiler). >3) I'd like to check at that two arrays have the same number of initializers. > I'd like this check at compile time, so I'd like to be able to write > > #if (num_elems(a) - num_elems(s)) > cause a deliberate compilation error > #endif > > But, uh-huhm, the 'sizeof' and the pointer arithmetic is not permitted > at pre-processing time. Any way to do this nicely? Do it at compile time. With any decent compiler, num_elems will be computed at compile time, the if-expression will evaluate to a constant, and if the condition is met, the compiler will eliminate the test and the "dead" code it controls. (If your compiler doesn't work this way, try to get a better compiler.) Of course, you cannot include illegal code to cause a compile-time error with this technique. ANSI corner: Use the assert macro in the ANSI header <assert.h>. If your compiler doesn't support this, it looks like this: <assert.h>: #undef assert /* because multiple includes of <assert.h> are allowed */ #if defined(NDEBUG) #define assert(ignore) ((void) 0) #else extern void gripe(const char *, int, const char *); #define assert(expr) \ ((expr) ? ((void) 0) : _gripe_(__FILE__, __LINE__, # expr)) #endif "gripe" just calls printf to print the file, line, and the text of the test which failed; it then aborts the program. To use it: assert(num_elems(a) == num_elems(s)); As noted above, when the test passes no code should be generated for the assertion. For production versions, just #define NDEBUG, and the preprocessor deletes the whole wretched mess. -- Steve Clamage, TauMetric Corp, steve@taumet.com
karl@haddock.ima.isc.com (Karl Heuer) (06/05/90)
In article <6644.26663D46@puddle.fidonet.org> cspw.quagga@p0.f4.n494.z5.fidonet.org (cspw quagga) writes: >2) I want to find out how many elements are in my initialized arrays. > #define num_elems(array) (sizeof(array)/(&array[1]-&array[0])) That denominator is always 1. You mean `(sizeof(array)/sizeof(array[0]))'. > Will this work, even in the presence of pad bytes? Yes. Arrays have no padding (though their elements might), and sizeof() does account for any padding. Personally, I prefer to work with #define endof(a) (&(a)[sizeof(a)/sizeof((a)[0])]) for (p = &a[0]; p < endof(a); ++p) ... >3) I'd like to check at that two arrays have the same number of initializers. > #if (num_elems(a) - num_elems(s)) > cause a deliberate compilation error > #endif (Note: the best way to force a compilation abort is with `#error' in ANSI C, which was designed for that purpose; it also generates a syntax error in pre-ANSI compilers if you put a leading blank on the line (` #error') to slip it past the pre-ANSI preprocessor.) > But, uh-huhm, the 'sizeof' and the pointer arithmetic is not permitted > at pre-processing time. Any way to do this nicely? Well, you could use `1/(num_elems(a) == num_elems(s))' in a nearby expression, but please keep my name out of the code. Karl W. Z. Heuer (karl@ima.ima.isc.com or harvard!ima!karl), The Walking Lint