[net.lang.c] C programming hint

kps@teddy.UUCP (07/10/85)

I found a way to initialize an array of characters without using a loop.
Here is the method I used:

	char blanks[SIZE];	/* declare array of SIZE elements */
	
	blanks[0] = ' ';	/* initialize 1st element */

	strncpy(blanks + 1, blanks, SIZE - 1);	/* initialize entire array */
		   ^^^       ^^^       ^^^
		    |         |         |
		destination  source   how many characters to copy 

The trick is to use strncpy in an almost recursive way.
Well, I hope you found this useful.

stew@harvard.ARPA (Stew Rubenstein) (07/11/85)

In article <899@teddy.UUCP> kps@teddy.UUCP (Kesavan P. Srinivasan) writes:
>I found a way to initialize an array of characters without using a loop.
>Here is the method I used:
>
>	char blanks[SIZE];	/* declare array of SIZE elements */
>	
>	blanks[0] = ' ';	/* initialize 1st element */
>
>	strncpy(blanks + 1, blanks, SIZE - 1);	/* initialize entire array */
>		   ^^^       ^^^       ^^^
>		    |         |         |
>		destination  source   how many characters to copy 
>
>The trick is to use strncpy in an almost recursive way.
>Well, I hope you found this useful.

This is not portable.  There is no guarantee that strncpy() copies
one char at a time in forward order.  If it is implemented using the
VAX MOVC3 instruction, for example, the overlap of the source and
destination strings does NOT affect the result!

Stew

gangal@petsd.UUCP (Dept 3271) (07/11/85)

In article <899@teddy.UUCP> kps@teddy.UUCP (Kesavan P. Srinivasan) writes:
>I found a way to initialize an array of characters without using a loop.
>Here is the method I used:
>
>       blanks[0] = ' ';        /* initialize 1st element */
>       strncpy(blanks + 1, blanks, SIZE - 1);  /* initialize entire array */


1)      This probably uses a loop (in strncpy)

2)      I don't know exactly what the standard C library does, but many
	string copy routines (in micro-code or higher level) check
	for overlapping strings and would process your request in reverse
	to avoid just the recursion you want.  (For instance, you may
	have a string in there to which you want to prepend a character.)



					bob

ark@alice.UUCP (Andrew Koenig) (07/11/85)

> I found a way to initialize an array of characters without using a loop.
> Here is the method I used:

> 	char blanks[SIZE];	/* declare array of SIZE elements */
	
> 	blanks[0] = ' ';	/* initialize 1st element */

> 	strncpy(blanks + 1, blanks, SIZE - 1);	/* initialize entire array */
> 		   ^^^       ^^^       ^^^
> 		    |         |         |
> 		destination  source   how many characters to copy 

Don't.  There is no guarantee that strncpy copies one character at a time.

mgh@mtunh.UUCP (Marcus Hand) (07/11/85)

> Reply-To: kps@teddy.UUCP (Kesavan P. Srinivasan)
> Keywords: strncpy
> Summary: initializing strings (arrays of characters)
> 
> I found a way to initialize an array of characters without using a loop.
> Here is the method I used:
> 
> 	char blanks[SIZE];	/* declare array of SIZE elements */
> 	
> 	blanks[0] = ' ';	/* initialize 1st element */
> 
> 	strncpy(blanks + 1, blanks, SIZE - 1);	/* initialize entire array */
> 		   ^^^       ^^^       ^^^
> 		    |         |         |
> 		destination  source   how many characters to copy 
> 
> The trick is to use strncpy in an almost recursive way.
> Well, I hope you found this useful.

Sorry to dissapoint you, but
	1.	strncpy() is implemented using a loop (this side effect
		wouldn't work if it wasn't);

	2.	it only works if strncpy is implemented by starting with the
		first character to be moved and not the last (you can move
		up and down a string in either direction). I.e. it's
		implementation dependent;
	
	3.	its not recursive or even analogous to recursion -- it just
		keeps copying the last character it moved;

	4.	whats wrong with memset() (memory(3))  --  I don't know
		whether its any more efficient, but its certainly
		clearer to the reader what you are trying to achieve,
		and safer because its not implementation dependant:

			rtn = memset (buffer, ' ', buflen);
	
	Hope this helps you.
-- 
			Marcus Hand	(mtunh!mgh)

ron@brl-tgr.ARPA (Ron Natalie <ron>) (07/12/85)

> I found a way to initialize an array of characters without using a loop.
> Here is the method I used:
> 
> 	strncpy(blanks + 1, blanks, SIZE - 1);	/* initialize entire array */
> 		   ^^^       ^^^       ^^^
> The trick is to use strncpy in an almost recursive way.

We call this "almost recursion" iteration, and all it does is hide the
loop in the strncpy function.

> Well, I hope you found this useful.

No, not really.

-Ron

chris@umcp-cs.UUCP (Chris Torek) (07/12/85)

> I found a way to initialize an array of characters without using a loop.
> Here is the method I used:
>
> 	char blanks[SIZE];	/* declare array of SIZE elements */
> 	blanks[0] = ' ';	/* initialize 1st element */
> 	strncpy(blanks + 1, blanks, SIZE - 1);	/* initialize entire array */

Beware, that won't work on Vax systems that use movc3 for string copies
(probably Sys VR2V2.2.2.2... [sorry :-)] and 4.3 both).
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 4251)
UUCP:	seismo!umcp-cs!chris
CSNet:	chris@umcp-cs		ARPA:	chris@maryland

guy@sun.uucp (Guy Harris) (07/12/85)

> I found a way to initialize an array of characters without using a loop. ...
> 	strncpy(blanks + 1, blanks, SIZE - 1);	/* initialize entire array */

Ummm... there *is* a loop there; it just happens to be hidden in the
"strncpy" routine.  In some C libraries on some machines, this uses a faster
sequence to copy the data than the fastest C loop.  On other machines,
"strncpy" is just the obvious C loop (and you pay the overhead of a
subroutine call).  On other machines, "strncpy" might not work with
overlapped strings...

The System V C library has a routine called "memset" which can be used to
set a block of bytes to a specific value.  Modulo the subroutine call
overhead, this is probably the most efficent way of initializing the array
(the "strncpy" has to fetch byte N to move it to byte N+1; the "memset" can
keep that byte in a register).

	Guy Harris

bright@dataio.UUCP (Walter Bright) (07/12/85)

In article <899@teddy.UUCP> kps@teddy.UUCP (Kesavan P. Srinivasan) writes:
>I found a way to initialize an array of characters without using a loop.
>	char blanks[SIZE];	/* declare array of SIZE elements */
>	
>	blanks[0] = ' ';	/* initialize 1st element */
>
>	strncpy(blanks + 1, blanks, SIZE - 1);	/* initialize entire array */
>
>The trick is to use strncpy in an almost recursive way.

	This will fail if strncpy() copies starting from the end of the source
string, rather than from the beginning. You are depending on an undefined
side effect of your implementation of strncpy().
	Try using memset():

	memset(blanks,' ',SIZE-1);

kps@teddy.UUCP (07/12/85)

	char blanks[SIZE];
	blanks[0] = ' ';
	strncpy(blanks + 1, blanks, SIZE - 1);	/* initialize entire array */

Here's what people said about my method:

From panda!talcott!harvard!stew
>This is not portable.  There is no guarantee that strncpy() copies
>one char at a time in forward order.  If it is implemented using the
>VAX MOVC3 instruction, for example, the overlap of the source and
>destination strings does NOT affect the result!

From panda!genrad!decvax!harpo!whuxlm!whuxl!houxm!ihnp4!mhuxn!mhuxr!ulysses!allegra!alice!ark
>Don't.  There is no guarantee that strncpy copies one character at a time.

From panda!talcott!harvard!seismo!umcp-cs!chris
>Beware, that won't work on Vax systems that use movc3 for string copies
>(probably Sys VR2V2.2.2.2... [sorry :-)] and 4.3 both).

From panda!genrad!decvax!harpo!whuxlm!whuxl!houxm!mtuxo!mtunh!mtung!mtunf!ariel!vax135!petsd!gangal
>2)      I don't know exactly what the standard C library does, but many
>	string copy routines (in micro-code or higher level) check
>	for overlapping strings and would process your request in reverse
>	to avoid just the recursion you want.  (For instance, you may
>	have a string in there to which you want to prepend a character.)

From panda!genrad!decvax!harpo!whuxlm!whuxl!houxm!mtuxo!mtunh!mgh
>	2.	it only works if strncpy is implemented by starting with the
>		first character to be moved and not the last (you can move
>		up and down a string in either direction). I.e. it's
>		implementation dependent;

Well, as you can probably see, I've been bludgeoned to death
with the fact that my method is implementation dependent and
that it won't work all the time.

I stand connected, er, I mean corrected.

Thanks for a humbling experience,
			B.K.

smk@axiom.UUCP (Steven M. Kramer) (07/12/85)

> From: kps@teddy.UUCP
> Subject: C programming hint
> 
> The trick is to use strncpy in an almost recursive way.

The problem in using strncpy for a ripple effect is that you are
inferring a feature of the implementation of strncpy.  For those systems
that implement it using a machine instruction or otherwise
semantically differently than you are used to, this will not work.
It certainly is not portable.
-- 
	--steve kramer
	{allegra,genrad,ihnp4,utzoo,philabs,uw-beaver}!linus!axiom!smk	(UUCP)
	linus!axiom!smk@mitre-bedford					(MIL)

brent@cadovax.UUCP (Brent Rector) (07/12/85)

In article <899@teddy.UUCP> kps@teddy.UUCP (Kesavan P. Srinivasan) writes:
>I found a way to initialize an array of characters without using a loop.
>Here is the method I used:
>
>	char blanks[SIZE];	/* declare array of SIZE elements */
>	
>	blanks[0] = ' ';	/* initialize 1st element */
>
>	strncpy(blanks + 1, blanks, SIZE - 1);	/* initialize entire array */
>		   ^^^       ^^^       ^^^
>		    |         |         |
>		destination  source   how many characters to copy 
>

It seems to me that all you have done is to move the loop into the
strncpy function at the cost of additional procedure call.  Also while
I expect the above will generally work I can think of a couple of bizarre
ways to implement strncpy that would cause the above to fail.  In general
I think overlapped moves produce machine dependent results.

-- 
--------------------------------------------------------------
Brent E. Rector - CONTEL CADO, Torrance, CA
{ decvax, hplabs, ihnp4, ucbvax, sdcrdcf }!trwrb!cadovax!brent
   { onecom, philabs, scgvaxd, ttidca, ucla-cs }!cadovax!brent
				 cadovax!brent@ucla-locus.ARPA

bo@enea.UUCP (Bo Steinholtz) (07/12/85)

In article <899@teddy.UUCP> kps@teddy.UUCP (Kesavan P. Srinivasan) writes:
>I found a way to initialize an array of characters without using a loop.
>Here is the method I used:
>
>	char blanks[SIZE];	/* declare array of SIZE elements */
>	
>	blanks[0] = ' ';	/* initialize 1st element */
>
>	strncpy(blanks + 1, blanks, SIZE - 1);	/* initialize entire array */
>		   ^^^       ^^^       ^^^
>		    |         |         |
>		destination  source   how many characters to copy 

Ah, how the heart of an old assembler language programmer rejoices!
For another description of this trick,
see e.g. the description of the MVC machine instruction in
"IBM System/360 Principles of Operation" from the sixties,
where it is pointed out that it may be employed to
initialize an array in one machine instruction.

However, the most authoritative (?) source on C,
Harbison/Steele: "C: A Reference Manual", Prentice-Hall 1984,
states in the definition of strncpy that:

	"The results are unpredictable if the two string
	arguments overlap in memory."

Thus, if strncpy is used, the trick is nonportable!

ed@zinfandel.UUCP (Ed Hirgelt) (07/13/85)

I may be mistaken, but this hint also has a problem in not null
terminating the string. strncpy stops at the first null character
or when the count is exceeded. Since the initial version of the
string has no null, one is never added to the string. This may
be what the poster intended, but he should never use that string
with any of the other string utilities (like strcmp, etc.)
-- 
Ed Hirgelt
Zehntel Automation Systems	{ihnp4 ucbvax}!zehntel!ed
2625 Shadelands Drive		zehntel!ed@Berkeley.ARPA
Walnut Creek, Ca 94598

root@bu-cs.UUCP (Barry Shein) (07/13/85)

I remember teaching that strncpy hack...except it was:

	mvi	str,c' '
	mvc	str+1(length-1),str

hey, if you're gonna make it machine-dependant

	!MAKE IT MACHINE DEPENDANT!

(where's my green card...)

	-Barry Shein, Boston University

ags@pucc-h (Dave Seaman) (07/13/85)

In article <476@mtunh.UUCP> mgh@mtunh.UUCP (Marcus Hand) writes
(Concerning "almost recursive" use of strncpy):

> Sorry to dissapoint you, but...
> 	
> 	3.	its not recursive or even analogous to recursion -- it just
> 		keeps copying the last character it moved;

The operation 

	blanks[0] = ' '
	blanks[i] = blanks[i-1]		for i = 1,2,...,SIZE-1

is recursive in the mathematical sense, just as the familiar definition 
of the factorial function,

	fact(0) = 1
	fact(n) = n * fact(n-1) for n > 0

is recursive.  The fact that it is possible to fill an array with blanks
or to compute the factorial function without resorting to functions or
procedures that call themselves does not mean the underlying definitions
are not recursive.

Both operations also have nonrecursive definitions:

	blanks[i] = ' '		for i = 1,2,...,SIZE-1

	fact(n) = GAMMA(n+1)	for n = 0,1,2, ...

-------------------------------------------------------------------------
>> 	char blanks[SIZE];	/* declare array of SIZE elements */
>> 	
>> 	blanks[0] = ' ';	/* initialize 1st element */
>> 
>> 	strncpy(blanks + 1, blanks, SIZE - 1);	/* initialize entire array */
>> 		   ^^^       ^^^       ^^^
>> 		    |         |         |
>> 		destination  source   how many characters to copy 
>> 
>> The trick is to use strncpy in an almost recursive way.
>> Well, I hope you found this useful.
-- 
Dave Seaman			 ..!pur-ee!pucc-h:ags

gam@amdahl.UUCP (G A Moffett) (07/14/85)

In article <899@teddy.UUCP> kps@teddy.UUCP (Kesavan P. Srinivasan) writes:
>I found a way to initialize an array of characters without using a loop.
>Here is the method I used:
>
>	char blanks[SIZE];	/* declare array of SIZE elements */
>	
>	blanks[0] = ' ';	/* initialize 1st element */
>
>	strncpy(blanks + 1, blanks, SIZE - 1);	/* initialize entire array */

This is machine-dependent so don't expect this to be portable.

Generally speaking, you shouldn't use the string library functions on
overlapping strings.


-- 
Gordon A. Moffett		...!{ihnp4,cbosgd,hplabs}!amdahl!gam

gwyn@BRL.ARPA (VLD/VMB) (07/14/85)

Warning!  The behavior of strncpy() on overlapping strings is
undefined.  Many implementations of strncpy() use a "block move"
machine instruction, which may or may not work the way you
expect when the source and destination overlap.

hamilton@uiucuxc.Uiuc.ARPA (07/15/85)

re: clever string fill
it's bad enough that his nifty idea is "wrong", but it ain't new either.
i'm sure i've seen that trick used in ibm 1401 autocoder...

gupta@asgb.UUCP (Yogesh K Gupta) (07/15/85)

> I found a way to initialize an array of characters without using a loop.
> Here is the method I used:
> 
> 	char blanks[SIZE];	/* declare array of SIZE elements */
> 	
> 	blanks[0] = ' ';	/* initialize 1st element */
> 
> 	strncpy(blanks + 1, blanks, SIZE - 1);	/* initialize entire array */
> 		   ^^^       ^^^       ^^^
> 		    |         |         |
> 		destination  source   how many characters to copy 
> 
> The trick is to use strncpy in an almost recursive way.
> Well, I hope you found this useful.

Unfortunately, strncpy uses the "loop" that you are trying to avoid.  It
also makes a redundant (in this case) check for the null character each time
through the loop that should be avoided.
-- 
Yogesh Gupta                           Advanced Systems Group,
{sdcrdcf, sdcsvax}!bmcg!asgb!gupta     Burroughs Corp., Boulder, CO.
--------------------------------------------------------------------
	All opinions contained in this message are my own and do not
	reflect those of my employer or the plant on my desk.

mah@asgb.UUCP (Mark Hamilton) (07/15/85)

> > I found a way to initialize an array of characters without using a loop.
> > Here is the method I used:
> > 
> > 	char blanks[SIZE];	/* declare array of SIZE elements */
> > 	
> > 	blanks[0] = ' ';	/* initialize 1st element */
> > 
> > 	strncpy(blanks + 1, blanks, SIZE - 1);	/* initialize entire array */
> > 		   ^^^       ^^^       ^^^
> > 		    |         |         |
> > 		destination  source   how many characters to copy 
> > 
> > The trick is to use strncpy in an almost recursive way.
> > Well, I hope you found this useful.
> 
> Unfortunately, strncpy uses the "loop" that you are trying to avoid.  It
> also makes a redundant (in this case) check for the null character each time
> through the loop that should be avoided.

One would hope that the compiler (or optimizer) would realize what's 
going on here, and do something a little more clever than looping.
Especially since this is a strncpy, so the check for the null character
isn't done.  I must admit that I am new to Unix C, but on VMS (and I
beleive TOPS20, for whoever uses that) C, the compiler will turn this
into a MOVC instruction (or a BLT on the '20).  These are both the accepted
method for filling a region.

Mark Hamilton
-- 
The opinions expessed above are -- or maybe they aren't...
	Mark Hamilton - Burroughs Advanced Systems Group
			Boulder, CO 80301
			ihnp4!sdcsvax!bmcg!asgb!mah

stew@harvard.ARPA (Stew Rubenstein) (07/17/85)

In article <730@asgb.UUCP> seismo!hao!asgb!mah (Mark Hamilton) writes:
>> > I found a way to initialize an array of characters without using a loop.
>> > Here is the method I used:
>> > 	strncpy(blanks + 1, blanks, SIZE - 1);	/* initialize entire array */
>> 
>> Unfortunately, strncpy uses the "loop" that you are trying to avoid.  It
>> also makes a redundant (in this case) check for the null character each time
>> through the loop that should be avoided.
>
>One would hope that the compiler (or optimizer) would realize what's 
>going on here, and do something a little more clever than looping.
>Especially since this is a strncpy, so the check for the null character
>isn't done.  I must admit that I am new to Unix C, but on VMS (and I
>beleive TOPS20, for whoever uses that) C, the compiler will turn this
>into a MOVC instruction (or a BLT on the '20).  These are both the accepted
>method for filling a region.
>
>Mark Hamilton

You are dreaming if you think that the compiler will turn a function call
into a single inline instruction.  This is an admirable dream, but a dream
nonetheless.  This gets compiled (by VMS VAX-11 C Version 2.0) into a
subroutine call.  There's no way to assure the compiler that this strncpy
is going to be pulled from the standard run-time library.  Suppose you
wanted to replace the standard strncpy (or more likely some other standard
library function, like malloc) with your own for some reason (debugging?
better error handling?)  Now won't you be annoyed if the compiler optimizes
this function call away?

Anyone know of any efforts to standardize an indication to the compiler
that it is or is not OK to compile standard library functions in-line?

Stew
{seismo,ut-sally}!harvard!rubenstein

johnston@uiucdcsb.Uiuc.ARPA (07/18/85)

/* Written  2:04 pm  Jul 10, 1985 by kps@teddy.UUCP in uiucdcsb:net.lang.c */
/* ---------- "C programming hint" ---------- */
I found a way to initialize an array of characters without using a loop.
Here is the method I used:

	char blanks[SIZE];	/* declare array of SIZE elements */
	
	blanks[0] = ' ';	/* initialize 1st element */

	strncpy(blanks + 1, blanks, SIZE - 1);	/* initialize entire array */
		   ^^^       ^^^       ^^^
		    |         |         |
		destination  source   how many characters to copy 

The trick is to use strncpy in an almost recursive way.
Well, I hope you found this useful.
/* End of text from uiucdcsb:net.lang.c */

lcc.niket@UCLA-LOCUS.ARPA (Niket K. Patwardhan) (07/19/85)

I scanned the C standards draft a while ago and remembered there was something
about builtins. Well, I went back and checked, and found there isn't any
declaration as such, but it does say (Page 68, Introduction of Library section)
that

"One implication of this restriction <....external identifiers starting with
_ are reserved ....> is that implementations may provide special semantics
for names starting with underscore. For example, _builtin_abs could be used
to <.....define an inline abs>."

It also warns that any function defined in a header file could be a macro,
and that if you wanted your own function you should use the #undef directive
to nullify any such macro definition before using your function. Thus an
implementor says

#define abs _builtin_abs

in his header file, and users would get the builtin abs normally. If they wanted
to use their own abs, they would #undef abs before using it.

lum@osu-eddie.UUCP (Lum Johnson) (07/19/85)

In article <913@teddy.UUCP> kps@teddy.UUCP writes:
>
>	char blanks[SIZE];
>	blanks[0] = ' ';
>	strncpy(blanks + 1, blanks, SIZE - 1);	/* initialize entire array */
>
> ... I've been bludgeoned to death with the fact that my method is
> implementation dependent and that it won't work all the time.

This actually works in assembly language for the PDP-10.

	movei t1," "		; put <SPACE> in reg
	movem t1,blanks		; deposit char in buffer
	move t1,[blanks,,blanks+1] ; control register for blt
	blt t1,blanks+size	; propagate char over buffer

The BLT iterates the copy-previous-char operation (specified in t1),
incrementing both halves of the control register (t1) until
blanks+size is reached.

Lum Johnson ..!cbosgd!osu-eddie!lum or lum@osu-eddie.uucp

joemu@nsc-pdc.UUCP (Joe Mueller) (07/19/85)

> > I found a way to initialize an array of characters without using a loop.
> > Here is the method I used:
> > 
> > 	char blanks[SIZE];	/* declare array of SIZE elements */
> > 	
> > 	blanks[0] = ' ';	/* initialize 1st element */
> > 
> > 	strncpy(blanks + 1, blanks, SIZE - 1);	/* initialize entire array */
> > 		   ^^^       ^^^       ^^^
> > 		    |         |         |
> > 		destination  source   how many characters to copy 
> > 
> > The trick is to use strncpy in an almost recursive way.
> > Well, I hope you found this useful.
> 
> Unfortunately, strncpy uses the "loop" that you are trying to avoid.  It
> also makes a redundant (in this case) check for the null character each time
> through the loop that should be avoided.
> 
> I would hope that the compiler (or optimizer) would realize what's 
> going on here, and do something a little more clever than looping.
> especially since this is a strncpy, so the check for the null character
> isn't done.  I must admit that I am new to Unix C, but on VMS (and I
> beleive TOPS20, for whoever uses that) C, the compiler will turn this
> in to a MOVC instruction (or a BLT on the '20).  These are both the accepted
> method for filling a region.

The most effecient way to initialize an array (or anything else) to anything
but zeros is to use the initializer construct. If you need it to be zeros,
any global will default to zero fill. This will only work for globals in most
current compilers but the new ansi standard will (I believe) allow
initialization of automatic aggregates as long as the initializer consists of
constant expressions and doesn't make any subroutine calls or use variables.
The following lines would initialize your blanks array as long as it has global
scope (not in a function):

char blanks[SIZE] = { ' ', ' ', ' ', ' ', ' ' };	/* 5 blanks */
char blanks[SIZE] = "      ";				/* 5 blanks */

This assumes a SIZE of 5, but you can do it for any SIZE;
You can even skip your array dimention like this:
char blanks[] = "      ";				/* 5 blanks */

If you want to know what I meant by the comments about the standard, let
me illustrate:

foo()
{
int bar[3] = { 3, 4, 5};					/* legal */
int baz[3] = { random(), open("foobar", O_RDONLY), bar[1]};	/* illegal */
}

joemu@nsc-pdc.UUCP (Joe Mueller) (07/19/85)

> Anyone know of any efforts to standardize an indication to the compiler
> that it is or is not OK to compile standard library functions in-line?
> 
> Stew
> {seismo,ut-sally}!harvard!rubenstein

The committee discussed the question and decided that it should be done within
the realm of "# pragma" lines. This means that any compiler may offer this
feature but it will not be something that will be standardized. The # pragma
line was added to the standard to give implementors an easy way to turn
switches on or off in the compiler without adding new keywords. The line
could be something like:

# pragma inline	strncpy, sin, cos, absf

The # pragma directive is discussed in section C.8.5 of the draft. It doesn't
say much other than it causes implementation defined things to occur. By the
way, if anyone wants a copy of the draft, I believe it's now available for
informal public comment through CEBEMA for about $20. If there's enough
interrest, I'll try to find the address to send your money to.

guy@sun.uucp (Guy Harris) (07/23/85)

> The most effecient way to initialize an array (or anything else) to anything
> but zeros is to use the initializer construct.

Only if you are initializing the array (or whatever) at initial execution
time for a non-"auto" array, or at procedure entry time for an "auto" array.
If, for example, you want to initialize it each time through a loop, this
won't work.

	Guy Harris

peter@baylor.UUCP (Peter da Silva) (07/25/85)

> In article <913@teddy.UUCP> kps@teddy.UUCP writes:
> >
> >	char blanks[SIZE];
> >	blanks[0] = ' ';
> >	strncpy(blanks + 1, blanks, SIZE - 1);	/* initialize entire array */
> >
> > ... I've been bludgeoned to death with the fact that my method is
> > implementation dependent and that it won't work all the time.
> 
> This actually works in assembly language for the PDP-10.
> 
And of course it's the STANDARD method of initialising an array in FORTH:

	: fill over c! dup 1+ cmove ;
-- 
	Peter da Silva (the mad Australian)
		UUCP: ...!shell!neuro1!{hyd-ptd,baylor,datafac}!peter
		MCI: PDASILVA; CIS: 70216,1076

tim@callan.UUCP (Tim Smith) (07/30/85)

> 	char blanks[SIZE];	/* declare array of SIZE elements */
> 	
> 	blanks[0] = ' ';	/* initialize 1st element */
> 
> 	strncpy(blanks + 1, blanks, SIZE - 1);	/* initialize entire array */

Danger Will Robinson! Danger Will Robinson!  Non-portable contruct.  Unsafe
assumptions about implementation of strncpy.  Danger Will Robinson!

If strncpy is done in assembly for efficiency, and the machine has a block
tranfer instruction, and the author of strncpy used it, and the machine is
smart about copying strings, then the above will fail, because the machine
will recognize that the source and destinations overlap, with the destination
above the source, so it will copy the string from the back.
-- 
					Tim Smith
				ihnp4!{cithep,wlbr!callan}!tim