[comp.lang.c++] Pointer arithmetic

kdq@demott.com (Kevin D. Quitt) (01/05/91)

    What about the subtraction of pointers to get a constant?  I discovered
that gcc does not allow:

	int = strchr( string, char ) - &string;

to determine the position of char within string.  Is there a (good) reason
for disallowing this?  BTW, Microsoft C *does* accept this.

-- 
 _
Kevin D. Quitt         demott!kdq   kdq@demott.com
DeMott Electronics Co. 14707 Keswick St.   Van Nuys, CA 91405-1266
VOICE (818) 988-4975   FAX (818) 997-1190  MODEM (818) 997-4496 PEP last

bothner@sevenlayer.cs.wisc.edu (Per Bothner) (01/05/91)

In article <1991Jan4.191051.3995@demott.com> kdq@demott.COM (Kevin D. Quitt) writes:
>
>    What about the subtraction of pointers to get a constant?  I discovered
>that gcc does not allow:
>	int = strchr( string, char ) - &string;
>to determine the position of char within string.  Is there a (good) reason
>for disallowing this?

Perhaps because it's wrong? It should be:
	int i = strchr( str, ch ) - str;
(Note: no '&' before the string.)

Also, you need a prototype for strchr, so that the compiler can
know that the return type is (char*) and not (int).
libg++ has such a prototype in <std.h>.

Once you make these fixes, I'm sure gcc/g++ will allow your example.


-- 
	--Per Bothner
bothner@cs.wisc.edu Computer Sciences Dept, U. of Wisconsin-Madison

kdq@demott.com (Kevin D. Quitt) (01/05/91)

    I originally posted to comp.lang.c++ (don't know how it got there):

>    What about the subtraction of pointers to get a constant?  I discovered
>that gcc does not allow:
>
>	int = strchr( string, char ) - &string;
>
>to determine the position of char within string.  Is there a (good) reason
>for disallowing this?  BTW, Microsoft C *does* accept this.


    I rapidly received two responses indicating that the & was the problem.
(Nobody picked on using int and char as variables :-)


    The & was "artistic" in my example.  Microsoft C does allow &string,
but provides a warning that the ampersand is ignored.

    The actual code is:


const unsigned char *chars   = "some string"
unsigned char pass[];

    c   = strchr( chars, toupper( pass[ i ]) ) - chars + 1;


    gcc would not accept this no matter what I did.

-- 
 _
Kevin D. Quitt         demott!kdq   kdq@demott.com
DeMott Electronics Co. 14707 Keswick St.   Van Nuys, CA 91405-1266
VOICE (818) 988-4975   FAX (818) 997-1190  MODEM (818) 997-4496 PEP last

tim@proton.amd.com (Tim Olson) (01/06/91)

In article <1991Jan5.001607.5915@demott.com> kdq@demott.COM (Kevin D. Quitt) writes:
|     The actual code is:
| 
| 
| const unsigned char *chars   = "some string"
| unsigned char pass[];
| 
|     c   = strchr( chars, toupper( pass[ i ]) ) - chars + 1;
| 
| 
|     gcc would not accept this no matter what I did.

The problem is the "unsigned" type specifier in the declaration for
chars.  Section 3.5.4.1 (Pointer declarators) states that

	For two pointer types to be compatible, both shall be
	identically qualified and both shall be pointers to
	compatible types.

The function "strchr" is defined to return a type "char *"; it is
not compatible with "chars", which is of type "unsigned char *".  Try
removing the "unsigned" specifier from the declaration for "chars", or
explicitly cast the result of the strchr() function to (unsigned char *).


--
	-- Tim Olson
	Advanced Micro Devices
	(tim@amd.com)

chip@tct.uucp (Chip Salzenberg) (01/08/91)

According to kdq@demott.COM (Kevin D. Quitt):
>    The actual code is:
>
>
>const unsigned char *chars   = "some string"
>unsigned char pass[];
>
>    c   = strchr( chars, toupper( pass[ i ]) ) - chars + 1;
>
>
>    gcc would not accept this no matter what I did.


If strchr() wasn't declared properly, gcc would complain.

But a more serious complaint is the lack of a check on the return
value of strchr().  It might be NULL, after all, in which case the
subtraction will send the resulting value into deep space.
-- 
Chip Salzenberg at Teltronics/TCT     <chip@tct.uucp>, <uunet!pdn!tct!chip>
       "If Usenet exists, then what is its mailing address?"  -- me
             "c/o The Daily Planet, Metropolis."  -- Jeff Daiell

rsargent@alias.UUCP (Richard Sargent) (01/08/91)

In article <1991Jan5.001607.5915@demott.com> kdq@demott.COM (Kevin D. Quitt) writes:
>
>const unsigned char *chars   = "some string"
>unsigned char pass[];
>
>    c   = strchr( chars, toupper( pass[ i ]) ) - chars + 1;
>
>

One thing that comes to mind is that a *very* fussy compiler, such
as gcc with -pedantic (?) turned on, would complain that the
difference could be between strings in two different address spaces.
This would result in a meaningless difference.

Now, by definition, strchr() returns a pointer to within the string
(or NULL, I think). But, the compiler may be ignoring what the
standard says the function does, and may just consider it as any
function returning a pointer to char. In the event that the 
character is NOT in the string, a NULL return value will result
in a meaningless difference.

Checking the return value and only taking the difference when
non-NULL may be enough. Or maybe the compiler is just too fussy.
Or maybe the compiler has a bug. Or ...