HP3000-L Archives

October 1998, Week 5

HP3000-L@RAVEN.UTC.EDU

Options: Use Monospaced Font
Show Text Part by Default
Show All Mail Headers

Message: [<< First] [< Prev] [Next >] [Last >>]
Topic: [<< First] [< Prev] [Next >] [Last >>]
Author: [<< First] [< Prev] [Next >] [Last >>]

Print Reply
Subject:
From:
Walter Murray <[log in to unmask]>
Reply To:
Walter Murray <[log in to unmask]>
Date:
Fri, 30 Oct 1998 21:43:16 GMT
Content-Type:
text/plain
Parts/Attachments:
text/plain (90 lines)
John Zoltak ([log in to unmask]) wrote:
: Here is a compilable code snippet in HP C/iX. I always get the Warning
: 604. I cannot think of a cast to eliminate it. According to the book;
:    "604 Pointers are not assignment-compatible.
: In an assignment expression, if both the left hand and right hand side
: expressions are pointers, then the right hand side expression must
: either be the same type as the left side expression, or a pointer to
: void.
: Correct the expression (possibly by inserting a cast).
: ANSI 3.3.16.1"
: So what am I missing. The right hand side IS a void so why do I get the
: warning?

: :ccxl ctest01;info="-Aa"
: WED OCT 28 1998  9:29 AM  Copyright Hewlett-Packard Co.  1984.
: PAGE     1
: HP C/iX HP31506 A.05.19
: "CTEST01"

:     1  0   # 1 "CTEST01.PUB.LIB"
:     1  0   #pragma intrinsic HPGETPROCPLABEL
:     2  0
:     3  0   short (*pASCII)(short word, short base, char *string);
:     4  0
:     5  0   void *load()
:     6  0   {
:     7  1      int pLabel;
:     8  1      HPGETPROCPLABEL("%ASCII%", &pLabel);
:     9  1      return (void*) pLabel;
:    10  1   }
:    11  0
:    12  0   void main()
:    13  0   {
:    14  1      pASCII = load();
:    15  1   }
: cc: "CTEST01.PUB.LIB", line 14: warning 604: Pointers are not
: assignment-compatible.

As I confessed earlier, the wording in the manual, an attempted
gross simplification of the wording in the C standard, is wrong.

The compiler is producing this ANSI-required diagnostic because,
strictly speaking, C does not approve of mixing function pointers
with other pointers, even pointers-to-void.  It's common to use
void* as a generic pointer, because any data pointer can be converted
to a void* and back again, without losing anything.  That's not
true of function pointers, however, because some implementations
may store function pointers in a format that won't fit in the
storage allocated for a void*.  (It works OK in HP C/iX; it
just isn't guaranteed to work with other compilers.)  To suppress
this warning, you can use a cast to promise the compiler you know
what you're doing.  Assuming you want to retain the prototype in
the declaration of pASCII, and assuming you really want to have
load() return a void*, simply rewrite your assignment as follows:

     pASCII = (short(*)(short, short, char*))load();

This says:  "Take the pointer-to-void returned by load(), pretend
that it's really a pointer to a function that takes two shorts and
a char* and returns a short, and store that pointer in pASCII."
(Isn't C beautiful! :-)

(Stop here if you are a pragmatist and just want to get rid of
the warning.)

To be more of a C purist, you would probably want to change the
return type of your load() function.  Assuming it will ultimately
be used to return function pointers for a variety of functions with
different signatures, you would probably have it return some generic
function pointer type, analogous to void*, but valid for functions.
Then the declaration might look like this:

     void (*load(void))()

This says that load is a function that returns a pointer to a
function that has no parameters and returns nothing, i.e., load()
returns a generic function pointer.

And you'd put a corresponding cast in the return statement:

     return (void(*)(void)) pLabel;

This will cause the compiler to recognize you as a C guru, and
it will be pleased.  However, you will still need a cast in the
assignment to pASCII.

Walter Murray
Hewlett-Packard
Support Technology Lab

ATOM RSS1 RSS2