[comp.lang.c] C pointer problems in VMS.

V053MF43@ubvmsc.cc.buffalo.EDU (Mike Ayers) (03/17/88)

    I have recently been having some big problems passing pointers in VMS C. 
Consider the following:

char *wr(a)
int a;
{ body }

main()
{
 printf(" %s ",wr(4));
}

    This compiles and links without any problems, but I get a stack dump when 
I run it. The same is true of the following:

main()
{
 char b[12];

 b[0]='A';
 strcpy(((&b)+1),"rf!");
 printf(" %s ",b);
}

    Once again it compiles and links without warning, but dumps the stack upon 
execution. I checked my trusty K&R (less trusty by the day, it seems), which 
said that this should be correct.
    I am working in VMS 4.7 . Under this version we must link to 
SYS$SHARE:VAXCRTL.EXE/SHARE instead of the default library. Has anyone else 
had this problem, and if so, what can be done about it? At present I am living 
in fear of library calls that I thought were legal.



   Me again . . .             Mike Ayers                 /|___/|
                                                        / ,  _ |
   INTERNET: V053MF43@UBVMS.BITNET or                   | O O  /
             V053MF43@UBVMS.CC.BUFFALO.EDU              /    /
   SNAILNET: 190 Minnesota Ave.                        |\  /      ARF!
             Buffalo, NY 14214                          ---
   BELLNET : (716)838-3696                               U

   DISCLAIMER: I _AM_ the infinite number of monkeys.

chris@mimsy.UUCP (Chris Torek) (03/18/88)

In article <12464@brl-adm.ARPA> V053MF43@ubvmsc.cc.buffalo.EDU (Mike Ayers)
[who suffers from the horrid fate of a gibberish login :-) ] writes [edited]:
>I am working in VMS 4.7.

>char *wr(a) int a; { body }
>main() { printf(" %s ",wr(4)); }

Whether this will work depends on the `body'.

>main() {
> char b[12];
> b[0]='A';
> strcpy(((&b)+1),"rf!");

This call is wrong.  Clearly you meant `&b[1]' (or `b+1').  `&b' is, in
K&R C, illegal (and compiles with a warning about `& before array
ignored' on many systems).  According to the dpANS, `&b' should produce
an object of type `pointer to array 12 of char', or (char (*)[12]).
This is no doubt what your compiler is doing.  This object has the
wrong type for an argument to strcpy; that alone suffices to warrant
the code's failure.

(The real reason it failed is different.  In fact, on a Vax, this
produces the same object code as if you had written

	strcpy(b + 12, "rf!");

In other words, it scribbles all over the stack.)
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain:	chris@mimsy.umd.edu	Path:	uunet!mimsy!chris

g-rh@cca.CCA.COM (Richard Harter) (03/18/88)

In article <12464@brl-adm.ARPA> V053MF43@ubvmsc.cc.buffalo.EDU (Mike Ayers) writes:
o	... with sundry problems
>char *wr(a)
>int a;
>{ body }

>main()
>{
		<------- char *wr() goes here, your code declares wr as
			 a function returning an int (the default if there
			 is no declaration.)
> printf(" %s ",wr(4));
>}

>main()
>{
> char b[12];

> b[0]='A';
> strcpy(((&b)+1),"rf!");

			The expression &b should be &b[0].  b is an array
			and is a pointer (sort of :-)).  You are passing
			a pointer to a pointer.  b[0] is the first element
			of b.  &b[0] points to it.

			I say 'sort of' because there are subtle differences
			between arrays and pointers in C.  Some people can
			explain the difference; others can explain trans-
			substantiation.  I shall attempt neither in a public
			forum.
> printf(" %s ",b);
>}
-- 

In the fields of Hell where the grass grows high
Are the graves of dreams allowed to die.
	Richard Harter, SMDS  Inc.

karl@haddock.ISC.COM (Karl Heuer) (03/21/88)

In article <25667@cca.CCA.COM> g-rh@CCA.CCA.COM.UUCP (Richard Harter) writes:
>In article <12464@brl-adm.ARPA> V053MF43@ubvmsc.cc.buffalo.EDU (Mike Ayers) writes:
>o	... with sundry problems
>>char *wr(a) int a; { body }
>>main() {
>		<------- char *wr() goes here, your code declares wr as
>			 a function returning an int (the default if there
>			 is no declaration.)

True, if wr() and main() were in separate files.  I assume from the way the
question was asked that the definition of wr() appeared above main() in the
same file, in which case the definition itself serves as a declaration.
(Also, I consider it bad practice to declare a function with local scope, so
I'd put it outside main() anyway, even if nobody else calls it.)

Even if that mistake was made, my knowledge of the VAX architecture suggests
that it would not have caused the problem, so I suspect that the bug lies in
the body of wr().

>>main() {
>> char b[12]; ...
>> strcpy(((&b)+1),"rf!");
>The expression &b should be &b[0].  b is an array and is a pointer (sort of
>:-)).  You are passing a pointer to a pointer.

You're right about the bug and the fix.  But &b is not a pointer to a pointer,
it's a pointer to an array (assuming the compiler handles this properly; PCC
doesn't).  The strcpy() function needs a pointer to a char, which is what
&b[0] yields.  Lint would have caught this -- doesn't DEC make a linter yet?

>I say 'sort of' because there are subtle differences between arrays and
>pointers in C [which I won't try to explain here].

I won't go through the whole explanation, but here's the Reader's Digest
version for those who are interested.  Arrays and pointers are completely
different entities.  In an rvalue context, an array expression is converted
into a pointer to its first element.  This is somewhat analogous to the way a
char expression is converted to int.

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

g-rh@cca.CCA.COM (Richard Harter) (03/22/88)

In article <3072@haddock.ISC.COM> karl@haddock.ima.isc.com (Karl Heuer) writes:
>In article <25667@cca.CCA.COM> g-rh@CCA.CCA.COM.UUCP (Richard Harter) writes:
>>>char *wr(a) int a; { body }
>>>main() {
>>		<------- char *wr() goes here, your code declares wr as
>>			 a function returning an int (the default if there
>>			 is no declaration.)
>
>True, if wr() and main() were in separate files.  I assume from the way the
>question was asked that the definition of wr() appeared above main() in the
>same file, in which case the definition itself serves as a declaration.
>(Also, I consider it bad practice to declare a function with local scope, so
>I'd put it outside main() anyway, even if nobody else calls it.)

	Consider me confused.  What do you mean by declaring a function with
local scope?  Are you saying that you are a one-function per file advocate
or that one shouldn't declare static functions?

	It does matter (but not in this case) if the function appears after
its use.  Put wr after main, and you will get nasty little messages about
redeclaring the type of wr.

>Even if that mistake was made, my knowledge of the VAX architecture suggests
>that it would not have caused the problem, so I suspect that the bug lies in
>the body of wr().

	As you say, there is no problem on a VAX, since pointers and ints
are the same size and have the same format, etc.  I believe you are correct
in saying that the earlier declaration is honored in code below.  I say
'believe' because that this is sort of thing that 'I prefer not to know'.
Declare everything right is my motto; anything else lays the groundwork
for cryptic bugs and exercises in working out what the compiler really did.
Life is too short to solve the problems created by taking shortcuts. :-)
-- 

In the fields of Hell where the grass grows high
Are the graves of dreams allowed to die.
	Richard Harter, SMDS  Inc.

karl@haddock.ISC.COM (Karl Heuer) (03/23/88)

In article <25834@cca.CCA.COM> g-rh@CCA.CCA.COM.UUCP (Richard Harter) writes:
>>(Also, I consider it bad practice to declare a function with local scope, so
>>I'd put it outside main() anyway, even if nobody else calls it.)
>
>Consider me confused.  What do you mean by declaring a function with
>local scope?  Are you saying that you are a one-function per file advocate
>or that one shouldn't declare static functions?

Neither.  I'm saying that I consider
    main() { extern void p(); p(); }
to be inferior to
    extern void p();
    main() { p(); }
Like it or not, the function "p" DOES have at least file scope, so you might
as well declare it that way.

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