[comp.lang.c] Passing sizes of arrays without a separate argument for the length

U23405@UICVM (Michael J. Steiner) (09/02/88)

I just got the idea of... well, let me give some examples:

BEFORE - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
main()
{
     char array[10];
     ...
     somefunc(array,10);
}

void somefunc(array,max)
char *array;
int max;
{
     int i;
     for (i = 1; i < max; ++i)
     ...
}


AFTER (MY IDEA) : - - - - - - - - - - - - - - - - - - - - - - - - - - - -
main()
{
     char array[10];
     ...
     array[0] = 10;
     somefunc(array);
}

somefunc(array)
char *array;
{
     int i;
     for (i = 1; i < array[0]; ++i)
     ...
}

In other words, I had an idea of putting the maximum array dimension in
the array itself. This should work with most arrays (since chars, floats,
unsigneds, shorts, etc. can be converted to integers). Also, there is always
room for the size of the array in array[0] (provided that the data starts
at array[1], as in PASCAL), since arrays should have at least a few
elements.

Any comments or suggestions are appreciated.

                                                 Michael Steiner
                                                 Email: U23405@UICVM.BITNET

evan@ctt.ctt.bellcore.com (Evan Bigall) (09/20/88)

In article <8809191507.AA17512@ucbvax.Berkeley.EDU> U23405@UICVM (Michael J. Steiner) writes:

>In other words, I had an idea of putting the maximum array dimension in
>the array itself. This should work with most arrays (since chars, floats,
>unsigneds, shorts, etc. can be converted to integers). Also, there is always
>room for the size of the array in array[0] (provided that the data starts
>at array[1], as in PASCAL), since arrays should have at least a few
>elements.
>
>Any comments or suggestions are appreciated.

Well, I can think of two potential problems first, if you have an array of char
you are limited to arrays 256 (depending on your byte size) bytes long.

Second, on many machines the operation of converting a float to an int is very
expensive (and on some it isnt of course).

You can avoid both these problems though, by just storing the actual int in
the beginning of the array (taking most probably 4 chars or half a float).
But, if you are going to go to that extreme why not just declare a struct 
and let the compiler do all the messy stuff for you?

I guess the real question is what exactly are you trying to accompish?  
If you are just trying to speed the code up by not passing an extra argument 
I dont think this is the way (of course I didnt read the 200 articles on
argument passing so take this with a grain of salt).

I'm also not sure if this is a good idea if your goal is to make the code is
more readable.  Most C programmers are used to arrays starting at 0 and would
probably go through and fix all your posthole errors for you.  You would have
to clearly document the whole business.

Evan


I barely have the authority to speak for myself, certainly not anybody else.
(201)699-4909 evan@ctt.bellcore.com or {backbone}!bellcore!ctt!evan

mesard@bbn.com (Wayne Mesard) (09/20/88)

From article <8809191507.AA17512@ucbvax.Berkeley.EDU>, by U23405@UICVM (Michael J. Steiner):
> In other words, I had an idea of putting the maximum array dimension in
> the array itself. This should work with most arrays (since chars, floats,
> unsigneds, shorts, etc. can be converted to integers). Also, there is always
> room for the size of the array in array[0] 

If I were to adopt your scheme, I'd want to do it consistently, since I
would otherwise hopelessly confuse myself and anyone reading my code (if
A[0] was sometimes data, and other times size info).  But most of the
time I either don't need to know an array's length: e.g., do you want to
store a strings allocated size, or it's current length?; or I get this
information elsewhere: from a #define'd constant (as should be the case
in your example).  This means that most of the time I'd be wasting the
storage in the zeroth element of the array as well as processing time to
assign it the length of the array unnecessarily.

And that's to say nothing of the inefficiency of having to dereference
to get the size (especially when the array is a float) when the
alternative is accessing a parameter whose value is most likely in a
register (again, as in your example).

Don't try to reinvent Pascal.  We still haven't recovered from the last
time it was attempted:-)

-- 
unsigned *Wayne_Mesard();    The last thing one knows in constructing
MESARD@BBN.COM               a work is what to put first.
BBN, Cambridge, MA                                      -- Blaise Pascal

kyriazis@rpics (George Kyriazis) (09/20/88)

In article <8809191507.AA17512@ucbvax.Berkeley.EDU> U23405@UICVM (Michael J. Steiner) writes:
>I just got the idea of... well, let me give some examples:
>
>     ...
>     array[0] = 10;
>     somefunc(array);
>     ...

	It certainly looks a good idea, and most BASIC interpreters use that
method.  The size of the array (or a character string varaible) accompanies
the array itself.  It is very useful for variable length strings, but it
takes up space in fixed with strings.  It is also used in variable record
files.
	Notice that in your way, the array index is limited to 255
(sizeof(char) == 1), and sometimes you'll need an array with more than 255
elements.  One alternative will be something like that:

	struct	array	{
			int	length;
			type	*data;
			};

where 'type' is your favourite data type.



  George Kyriazis
  kyriazis@turing.cs.rpi.edu
------------------------------

brianm@sco.COM (Brian Moffet) (09/21/88)

In article <8809191507.AA17512@ucbvax.Berkeley.EDU> U23405@UICVM (Michael J. Steiner) writes:
>
>In other words, I had an idea of putting the maximum array dimension in
>the array itself. This should work with most arrays (since chars, floats,

From what I have seen of BCPL (working with the translations on the
Amiga OS) this is classified as a BSTRING.  The size of the string is
the first element (up to 256 chars) and the string follows.

All in all a good idea, but sometimes really confusing when you have
to bit-shift the pointers by 2 to use them in C.  (BCPL pointers are
in word addressing, not byte addressing ).

brian moffet

bph@buengc.BU.EDU (Blair P. Houghton) (09/21/88)

In article <8809191507.AA17512@ucbvax.Berkeley.EDU> U23405@UICVM (Michael J. Steiner) writes:
>BEFORE - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
>main()
>{
>     char array[10];
>     ...
>     somefunc(array,10);
>}
[...you get the point...]
>
>AFTER (MY IDEA) : - - - - - - - - - - - - - - - - - - - - - - - - - - - -
>main()
>{
>     char array[10];
>     ...
>     array[0] = 10;
>     somefunc(array);
>}
>
>In other words, I had an idea of putting the maximum array dimension in
>the array itself. This should work with most arrays (since chars, floats,
>unsigneds, shorts, etc. can be converted to integers). Also, there is always
>room for the size of the array in array[0] (provided that the data starts
>at array[1], as in PASCAL), since arrays should have at least a few
>elements.

Works fine if you're prepared to keep track of all those casts.  You also
need to remember always that a "char array[10]" is {array[0],...,array[9]}.

Essentially, since you are "creating" the extra data element array[0]
expressly to pass the array size, it seems that you gain little by this
trick.  There's no memory-usage difference inherent in the two schemes.

Actually, it looks like a Great Obfuscation; a logical extension
would be to create "char array[MAX]" and cast _every_ member to something
other than char.  You could effectively give every variable in the program
the same name and a number by which it is truly identified.

It might have uses as a sort of nebulous database, but then that's
what ASCII files are for...

You're better off with "somefunc(array,MAX)"

				--Blair
				  "...but then that's what ASCII
				   files are for..."
				   -famous last words

djones@megatest.UUCP (Dave Jones) (09/21/88)

 In article <8809191507.AA17512@ucbvax.Berkeley.EDU> U23405@UICVM (Michael J. Steiner) writes:
)BEFORE - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
)main()
){
)     char array[10];
)     ...
)     somefunc(array,10);
)}
)
)AFTER (MY IDEA) : - - - - - - - - - - - - - - - - - - - - - - - - - - - -
)main()
){
)     char array[10];
)     ...
)     array[0] = 10;
)     somefunc(array);
)}
)

Try this:

typedef struct
{
  int size;
  char* contents;
}Var_array;


main()
{
  char contents[10];
  Var_array array;
  array.size = sizeof(contents);
  array.contents = contents;

  somefunc(array);
}

/* Works good. Lasts a long time. */

dave@onfcanim.UUCP (Dave Martindale) (09/21/88)

In article <8809191507.AA17512@ucbvax.Berkeley.EDU> U23405@UICVM (Michael J. Steiner) writes:
>
>AFTER (MY IDEA) : - - - - - - - - - - - - - - - - - - - - - - - - - - - -
>main()
>{
>     char array[10];
>     ...
>     array[0] = 10;
>     somefunc(array);
>}

Hmm, how about

	char array[256];

	array[0] = 256;

Assuming you have 8-bit bytes, this doesn't work very well.
In fact, if you have signed characters, any char array of length >= 128
doesn't work.