[comp.lang.c] Does ANSI C have lengthof

neville%zodiac@ads.arpa (Neville Newman) (09/03/87)

#From: Walter Bright <bright@dataio.Data-IO.COM>
#
#In article <761@cg-atla.UUCP> mallett@cg-atla.UUCP (Bruce Mallett) writes:
# #     I always define a macro "lengthof()" in my standard header file to
# #return the length of an array.  The definition looks something like:
# #   #define lengthof(x)  ( sizeof(x)/sizeof(x[0]) )
# #This is the kind of thing that would be better built into the compiler
# #much as is sizeof().
#
#I would rather it not be built into the compiler, as it is such an easy
#macro (I use the same macro myself). One thing I want, which the committee
#always seems to poo-poo, is a typeof. Having a typeof would make
#creation of 'generic' routines possible:
#
#	#define swap(a,b)	{ typeof(a) tmp; tmp = a; a = b; b = tmp; }
#	
#A typeof capability is rather trivial to implement in the compile itself
#(at least it is on my compiler!).
#

i wholeheartedly agree - lengthof() is such an easy macro it need not be
implemented in the compiler, and typeof() is a very useful pseudo-function
to have in the compiler.  i implemented typeof() in pcc a couple of years
ago, it was quite simple.  Sorry, but i don't have the diffs.

							-neville

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
U.S. Mail:  Neville D. Newman
	    Advanced Decision Systems
	    201 San Antonio Circle, Suite 286
	    Mountain View, CA  94040-1289

Phone:	    (415) 941-3912
Net mail:   neville@ads.arpa	(internet-relative)

jv@mhres.mh.nl (Johan Vromans) (09/04/87)

In article <9154@brl-adm.ARPA> neville%zodiac@ads.arpa (Neville Newman) writes:
>i wholeheartedly agree - lengthof() is such an easy macro it need not be
>implemented in the compiler, and typeof() is a very useful pseudo-function
>to have in the compiler.

I think there is more need for these functions in the pre-processor:

    # if sizeof (char*) == sizeof (int)
    typedef int numptr;
    # else
    # if sizeof (char*) == sizeof (long)
    typedef long numptr;
    # endif
    # endif
    # if unknown (typeof (numptr))
    .... error ....
    # endif


-- 
Johan Vromans                              | jv@mh.nl via European backbone
Multihouse N.V., Gouda, the Netherlands    | uucp: ..{?????!}mcvax!mh.nl!jv
"It is better to light a candle than to curse the darkness"

gwyn@brl-smoke.ARPA (Doug Gwyn ) (09/04/87)

In article <1265@mhres.mh.nl> jv@mhres.mh.nl (Johan Vromans) writes:
-    # if sizeof (char*) == sizeof (int)
-    typedef int numptr;
-    # else
-    # if sizeof (char*) == sizeof (long)
-    typedef long numptr;
-    # endif
-    # endif
-    # if unknown (typeof (numptr))
-    .... error ....
-    # endif

99 times out of 100, the above should be written as:
	typedef char *numptr;
People should STOP trying to do integer arithmetic with what are
nominally pointer values -- it is most unlikely to be portable,
and practically all portable uses do not require such kludgery!

jv@mhres.mh.nl (Johan Vromans) (09/05/87)

In article <6404@brl-smoke.ARPA> gwyn@brl.arpa (Doug Gwyn (VLD/VMB) <gwyn>) writes:
>People should STOP trying to do integer arithmetic with what are
>nominally pointer values -- it is most unlikely to be portable,
>and practically all portable uses do not require such kludgery!

I agree -- but there are cases where this kind of arithmetic is
unavoidable, e.g. the relocation of a disk-image of a program to a memory
image. But maybe you are right - including provisions in the compiler or
the pre-processor to make it easy to write non-portable programs should be
avoided. 
-- 
Johan Vromans                              | jv@mh.nl via European backbone
Multihouse N.V., Gouda, the Netherlands    | uucp: ..{?????!}mcvax!mh.nl!jv
"It is better to light a candle than to curse the darkness"

karl@haddock.ISC.COM (Karl Heuer) (09/05/87)

In article <1265@mhres.mh.nl> jv@mhres.mh.nl (Johan Vromans) writes:
>I think there is more need for these functions in the pre-processor:
>    # if sizeof (char*) == sizeof (int)

I've often wanted this sort of thing myself, but have grudgingly had to accept
the fact that a preprocessor that only examines "#" lines cannot possibly
understand "sizeof(time_t)".

But, ignoring for the moment the question of whether it's "good" that the
preprocessor doesn't know C, this enhancement shouldn't require all that much
"spurious knowledge", should it?  In particular, couldn't one write a cpp that
recognizes "typedef" declarations?  Such a preprocessor ought to be able to
handle any "sizeof(TYPE)" expression, and I'd be willing to do without
"sizeof(EXPR)".

Has anyone tried to write such a preprocessor?  Or is the problem more subtle
than this?  (Restricted-scope typedefs complicate things, but not much; and
nobody uses them, anyway.)

Karl W. Z. Heuer (ima!haddock!karl or karl@haddock.isc.com), The Walking Lint

peter@sugar.UUCP (Peter da Silva) (09/06/87)

> I think there is more need for these functions in the pre-processor:
> 
>     # if sizeof (char*) == sizeof (int)
>     typedef int numptr;
>     # else
>     # if sizeof (char*) == sizeof (long)
>     typedef long numptr;
>     # endif
>     # endif
>     # if unknown (typeof (numptr))
>     .... error ....
>     # endif

Well, first of all the preprocessor doesn't know the first thing about
typedef, other than it's a character string it's copying and ignoring.
The preprocessor doesn't know a type from a keyword. It probably doesn't
know from sizeof, either... it only knows about constants that have been
defined to it with #define. Even if it knows sizeof(int), it shouldn't
know about (for example) sizeof(numptr) or sizeof(struct foo).

Secondly:

     # if sizeof (char*) == sizeof (int)
     #  define NUMPTR int
     # else
     # if sizeof (char*) == sizeof (long)
     #  define NUMPTR long
     # endif
     # endif
     # if !defined(NUMPTR)
     .... error ....
     # endif

Finally, I do think typeof would be a great addition to the language.
-- 
-- Peter da Silva `-_-' ...!seismo!soma!uhnix1!sugar!peter
--                 'U`  <-- Public domain wolf.

peter@sugar.UUCP (Peter da Silva) (09/06/87)

>                                   In particular, couldn't one write a cpp that
> recognizes "typedef" declarations?  Such a preprocessor ought to be able to
> handle any "sizeof(TYPE)" expression, and I'd be willing to do without
> "sizeof(EXPR)".

It would also have to recognise structures.

typedef struct {
	something humungous with all sorts of
	arrays, pointers, enums, bit feilds, and
	unions
} zot;

#if sizeof(zot) > BUFSIZ
#define BUFFERSIZE sizeof(zot)
#else
#define BUFFERSIZE BUFSIZ
#endif

I can't see how cpp could do that without learning most of 'C'.
-- 
-- Peter da Silva `-_-' ...!seismo!soma!uhnix1!sugar!peter
--                 'U`  <-- Public domain wolf.

jagardner@orchid.UUCP (09/09/87)

In article <5360@utcsri.UUCP> flaps@utcsri.UUCP (Alan J Rosenthal) writes:
> [...]
>
>Besides Doug Gwyn's completely-correct comment that you should be
>saying "typedef char *numptr", this facility currently exists anyway:
>

According to the draft ANSI standard, "The expression shall be an
integral constant expression that shall not contain a sizeof operator" ...
This is in section 3.8.1, in reference to the "constant expression that
controls conditional inclusion". (draft Oct 1 1986)
I don't think it's cpp's place to know machine constants like sizeof.
The draft allows "void *" (generic pointer), so that should solve your
problems.

David Tanguay

jv@mhres.mh.nl (Johan Vromans) (09/09/87)

In article <5360@utcsri.UUCP> flaps@utcsri.UUCP (Alan J Rosenthal) writes:
|
|In article <1265@mhres.mh.nl> jv@mhres.mh.nl (Johan Vromans) writes:
|>I think there is more need for these functions in the pre-processor:
|>
|>    # if sizeof (char*) == sizeof (int)
|>    [...]
|>    # endif
|
|Besides Doug Gwyn's completely-correct comment that you should be
|saying "typedef char *numptr", this facility currently exists anyway:
|
|    #if sizeof(char *) == sizeof(int)
|    [...]
|    #endif
|

Has your C-preprocessor "sizeof" built-in? Quite exceptional.

|And, of course, you could always use "#define numptr int" so that you
|could later "#ifdef numptr".

The point is that on 16/32 bit machines (like IBM-PC) I need to have a
"long" hole to store a pointer (for whatever purpose), and on 16 bit
machines I need an "int" hole. And I want the pre-processor and/or
compiler to arrange this for me, so I have portable sources.


-- 
Johan Vromans                              | jv@mh.nl via European backbone
Multihouse N.V., Gouda, the Netherlands    | uucp: ..{?????!}mcvax!mh.nl!jv
"It is better to light a candle than to curse the darkness"

denbeste@bgsuvax.UUCP (William C. DenBesten) (09/09/87)

in article <1059@haddock.ISC.COM>, karl@haddock.ISC.COM (Karl Heuer) says:

>>I think there is more need for these functions in the pre-processor:
>>    # if sizeof (char*) == sizeof (int)
 
> Such a preprocessor ought to be able to
> handle any "sizeof(TYPE)" expression, and I'd be willing to do without
> "sizeof(EXPR)".

I would even be willing to do without TYPEs defined with typedef.  All that
I need (now :-) is the built ins (int, char*, long, char, etc).

---
          William C. DenBesten | CSNET denbeste@research1.bgsu.edu
      Dept of Computer Science | UUCP  ...!cbosgd!osu-cis!bgsuvax!denbeste
Bowling Green State University |
  Bowling Green, OH 43403-0214 |

wagner@iaoobelix.UUCP (09/14/87)

I don't expect any preprocessor to know about the sizes of certain
types. This can cause strange and weird confusions if you use cpp e.g.
for CProlog programs (like me) or for other types of non-C text
pre-processing purposes. Knowledge about sizes of data objects
definitely belongs to the semantics of the language C, and cannot be
handled by a generic cpp!

Juergen Wagner,		     (USENET) ...seismo!unido!iaoobel!wagner
("Gandalf")			 Fraunhofer Institute IAO, Stuttgart

karl@haddock.UUCP (09/17/87)

In article <6700012@iaoobelix.UUCP> wagner@iaoobelix.UUCP writes:
>I don't expect any preprocessor to know about the sizes of certain types.
>This can cause strange and weird confusions if you use cpp e.g.  for CProlog
>programs (like me) or for other types of non-C text pre-processing purposes.
>Knowledge about sizes of data objects definitely belongs to the semantics of
>the language C, and cannot be handled by a generic cpp!

Actually, the usual implementation of cpp already knows a lot about the
*syntax* of C -- comments, single quotes, double quotes, and backslash.  Thus,
it is not a "generic" preprocessor -- if you feed it
  if str = "\" then call dochar(BACKSLASH) endif
(where BACKSLASH is a token that should be expanded, and the language is one
that does not use the backslash character as an escape) it will almost
certainly do the wrong thing.

Also, knowledge about the sizes of types shouldn't cause the confusion you
imply -- the only place the preprocessor would use this information is to
resolve directives like "#if (sizeof(int) > 2)", which you would probably not
be using in your non-C program.

In fact, the existing directive "#if (0 < 1-2-3)" does the "wrong" thing if
I'm using cpp to preprocess APL, because C semantics are used to evaluate
preprocessor expressions.

(Having said all this, I should remark that I do not think the preprocessor
should know more about C.  I agree with the conclusion but not the argument.)

Karl W. Z. Heuer (ima!haddock!karl or karl@haddock.isc.com), The Walking Lint