[comp.lang.c] Non-Portable pointer assignment?

roy%cybrspc@cs.umn.edu (Roy M. Silvernail) (06/03/91)

(no, this isn't compiler-specific :-)

I use Turbo C, and sometimes get the warning "Non-portable pointer
assignment" when I do something like this:

foo(char *p) {
    char *q;

    q = strchr(p,'x');  /* this line gets complaints */
}

TFM says strchr() returns pointer to char, and the pointer I'm assigning
to is a pointer to char, so I'm in the dark.  On my platform, the code
works, but I try to write portably.

So, what's the proper (perhaps the ANSI) way to handle such an
assignment?  If Turbo is right, this snip of code will fail on other
machines or other compilers.
--
Roy M. Silvernail --  roy%cybrspc@cs.umn.edu - OR-  cybrspc!roy@cs.umn.edu
  perl -e '$x = 1/20; print "Just my \$$x! (adjusted for inflation)\n"'
        "What do you mean, you've never been to Alpha Centauri?"
                                               -- Prostetnic Vogon Jeltz

darcy@druid.uucp (D'Arcy J.M. Cain) (06/03/91)

In article <mccX31w164w@cybrspc> Roy M. Silvernail writes:
>I use Turbo C, and sometimes get the warning "Non-portable pointer
>assignment" when I do something like this:
>foo(char *p) {
>    char *q;
>
>    q = strchr(p,'x');  /* this line gets complaints */
>}
That's because the compiler sees you trying to assign an int to a pointer
to character.  To my mind it is being too polite.  It should say "Assignment
of pointer from integer lacks a cast" as well as telling you that strchr
is used without being declared.  Note that with Turbo C, like many other
ANSI compilers, will let you turn on lots of warnings and if you had done
so it would have caught this. (*)

>TFM says strchr() returns pointer to char, and the pointer I'm assigning
>to is a pointer to char, so I'm in the dark.  On my platform, the code
>works, but I try to write portably.
Unfortunately the compiler hasn't read TFM.  It doesn't know what strchr
returns.  It also doesn't know what arguments it expects so it can't
check them for you (they're fine here.)  To protect yourself you should
include the line:

extern char *strchr(const char *str, int ch);

or even better:

#include <string.h>

BTW, TFTM (The fine Turbo manual) shows you which header file(s) you
should include if you call a function.  If you include the ones it
indicates you will save yourself lots of grief one day.

>So, what's the proper (perhaps the ANSI) way to handle such an
>assignment?  If Turbo is right, this snip of code will fail on other
>machines or other compilers.
It might fail With Turbo with a different memory model.

(*) My favorite CFLAGS with GNU C:
    CFLAGS = -O -Wall -ansi -pedantic
and I still expect my programs to compile with no errors or warnings.

-- 
D'Arcy J.M. Cain (darcy@druid)     |
D'Arcy Cain Consulting             |   There's no government
Toronto, Ontario, Canada           |   like no government!
+1 416 424 2871                    |

lion@dat1hb.north.de (Daniel Tietze) (06/03/91)

roy%cybrspc@cs.umn.edu (Roy M. Silvernail) writes:

> foo(char *p) {
>     char *q;
> 
>     q = strchr(p,'x');  /* this line gets complaints */
> }
> 
Try q=strchr(p,"x"); , this should work. If I'm not mistaken, TC uses
'x' to denote a string and "x" to denote a char. At least, it always
works this way when I get that error message (and, being something of a
C novice, I get it rather more often than the average C programmer).
    Daniel


+------------------------------------------------------------------+
| Daniel Tietze, 2800 Bremen 1,  Tel.(voice) : 0421/448806         |
|-=============- DATELINE Communications, Bremen.  The home of DMS |
| Mail: (private) lion@dat1hb.north.de (univ) E07J@DHBRRZ41.BITNET |
|-====- DMS-Support: dateline@dat1hb.north.de                      |
+------------------------------------------------------------------+

roy%cybrspc@cs.umn.edu (Roy M. Silvernail) (06/04/91)

darcy@druid.uucp (D'Arcy J.M. Cain) writes:

> That's because the compiler sees you trying to assign an int to a pointer
> to character.  To my mind it is being too polite.  It should say "Assignment
> of pointer from integer lacks a cast" as well as telling you that strchr
> is used without being declared.

To tell the truth, I'd rather it have been a fatal compile error.  That
would have been more helpful to me that a warning and Doing The Right
Thing.

> Note that with Turbo C, like many other
> ANSI compilers, will let you turn on lots of warnings and if you had done
> so it would have caught this. (*)

And so I shall, believe me.  (that's what I get for hacking way past my
bedtime :-)

> BTW, TFTM (The fine Turbo manual) shows you which header file(s) you
> should include if you call a function.  If you include the ones it
> indicates you will save yourself lots of grief one day.

Agreed, as does the help function in TC IDE, and the THELP TSR.
Unfortunately, I got one of those occasional recto-cranial displacements
and neglected to look at them.

> (*) My favorite CFLAGS with GNU C:
>     CFLAGS = -O -Wall -ansi -pedantic
> and I still expect my programs to compile with no errors or warnings.

I'll see if I can get Turbo to act similarly, although I've already had
dos.h fail with the 'ANSI keywords only' directive enabled.  I suppose I
should just chuck DOS for an operating system.  (it'd be easier to get
GCC, too)

Thanks for the help!
--
Roy M. Silvernail --  roy%cybrspc@cs.umn.edu - OR-  cybrspc!roy@cs.umn.edu
  perl -e '$x = 1/20; print "Just my \$$x! (adjusted for inflation)\n"'
        "What do you mean, you've never been to Alpha Centauri?"
                                               -- Prostetnic Vogon Jeltz

boyd@prl.dec.com (Boyd Roberts) (06/05/91)

In article <JXey32w164w@dat1hb.north.de>, lion@dat1hb.north.de (Daniel Tietze) writes:
> roy%cybrspc@cs.umn.edu (Roy M. Silvernail) writes:
> 
> >     q = strchr(p,'x');  /* this line gets complaints */
> > }
> > 
> Try q=strchr(p,"x"); , this should work. If I'm not mistaken, TC uses
> 'x' to denote a string and "x" to denote a char.

Eh?  'x' is a char, while "x" is a string.  He probably needs:

    extern char *strchr();

Somewhere before strchr() is used, but within the same scope.


Boyd Roberts			boyd@prl.dec.com

``When the going gets wierd, the weird turn pro...''

suhonen@kunto.jyu.fi (Timo Suhonen) (06/05/91)

lion@dat1hb.north.de (Daniel Tietze) writes:

   Try q=strchr(p,"x"); , this should work. If I'm not mistaken, TC uses
   'x' to denote a string and "x" to denote a char.

Sorry, you are mistaken. 'x' is a single char and "x" is a string.

--
Timo                 "I am logged in, therefore I am"                 Suhonen
suhonen@jyu.fi suhonen@euler.jyu.fi suhonen@kunto.jyu.fi suhonen@nic.funet.fi
   Opinions(?) are mine (if not stolen), NOT those of Univ. of Jyvaskyla.

wirzeniu@klaava.Helsinki.FI (Lars Wirzenius) (06/05/91)

In article <1991Jun5.085138.21366@prl.dec.com> boyd@prl.dec.com (Boyd Roberts) writes:
>Eh?  'x' is a char, while "x" is a string.

Actually, 'x' is an int. (Being picky, I know.)
-- 
Lars Wirzenius     wirzeniu@cc.helsinki.fi

mcdaniel@adi.com (Tim McDaniel) (06/06/91)

Followups directed to comp.std.c.

In article <1991Jun5.150527.22942@klaava.Helsinki.FI>
wirzeniu@klaava.Helsinki.FI (Lars Wirzenius) writes:

   Actually, 'x' is an int. (Being picky, I know.)

It's not "picky"; it can be crucial.  I decided to use
`self-documenting code', as it were, to show the space necessary for
nul bytes, ',' between concatenated strings, and such.

   p = malloc(strlen(s) + sizeof '\0');

It took me a while to figure out that I ought to change it to

   p = malloc(strlen(s) + sizeof (char) '\0');

because sizeof '\0' is 4 on our machines.  Because of FlexeLint (with
a very rare bug), our non-ANSI compilers, and the fact that it's
actually our own MEMmalloc, I actually had to write something like

   p = MEMmalloc((ulong) strlen(s) + (ulong) sizeof ((char) '\0'));

Gak!  I just realized, however, that

   p = malloc(strlen(s) + sizeof "");

should work for ANSI environments.

So why in creation was 'x' ever specified to be int?  Why not char,
with the usual widening in expressions?  And why did X3J11 specify
that the types of enum constants were int, rather than the same type
as the underlying enum type?  It is HIGHLY disconcerting to discover
that a "character constant" is not of type char, and an "enumeration
constant" is not of its enumerated type.

--
   "Of course he has a knife; he always has a knife.  We all have knives.
   It's 1183 and we're barbarians."
Tim McDaniel                 Applied Dynamics Int'l.; Ann Arbor, Michigan, USA
Internet: mcdaniel@adi.com                UUCP: {uunet,sharkey}!amara!mcdaniel

newsuser@oliver.SUBLINK.ORG (Ugo Cei) (06/08/91)

boyd@prl.dec.com (Boyd Roberts) writes:

>Eh?  'x' is a char, while "x" is a string. [...]

Eh? 'x' is an int. Try printing "sizeof 'x'".
-- 
**************** | Ugo Cei            | home:    newsuser@oliver.sublink.org
*    OLIVER    * | Via Colombo 7      | office:  cei@ipvvis.unipv.it
**************** | 27100 Pavia ITALY  |       "Real Programs Dump Core"