Confusing problems with X libraries and headers 
Author Message
 Confusing problems with X libraries and headers

Code excerpt:

void Xmx_Unhighlight_Border (A_Gadget)
    XmGadget A_Gadget;                  /* A */
{
        register int X = A_Gadget->rectangle.x;  /* B */

Now this code #includes (indirectly) an O.S. vendor's header
file xxx containing

typedef struct _XmGadgetRec  * XmGadget;  /* C */

Doesn't that mean XmGadget is a variable that points to an
object typedef'd as _XmGadgetRec  ?  But the compiler accepted
it until.....

In an O.S. upgrade, the vendor screwed up, and failed to ensure
that header file xxx #included header file yyy which contained
the definition

typedef struct _XmGadgetRec  
{
   zzz  rectangle;
   etc.

Now, it won't compile, but the error message is at line /* B */

Is it a compiler bug to NOT complain about line /* C */
something like "_XmGadgetRec is undefined" ?

Is it a compiler bug to NOT complain about line /* A */
something like "XmGadget is a variable, not a type" ?

(I realize these messages are not cryptic enough for C, but
you get the idea anyway.)

If I put #include yyy in our code, am I just covering up a bunch
of bugs and invited bigger trouble later?
--



Mon, 18 Mar 2002 03:00:00 GMT  
 Confusing problems with X libraries and headers

[This is really about pointers to incomplete structures, despite the title.]

Quote:
> void Xmx_Unhighlight_Border (A_Gadget)
>     XmGadget A_Gadget;                  /* A */
> {
>         register int X = A_Gadget->rectangle.x;  /* B */

> Now this code #includes (indirectly) an O.S. vendor's header
> file xxx containing

> typedef struct _XmGadgetRec  * XmGadget;  /* C */

> Doesn't that mean XmGadget is a variable that points to an
> object typedef'd as _XmGadgetRec  ?  But the compiler accepted
> it until.....

No, it declares a type.  XmGadget is a type that can be used to create
pointers to an incomplete struct.  (Yeuch, I hate structs and pointers hidden
behind typedefs.)

Quote:
> In an O.S. upgrade, the vendor screwed up, and failed to ensure
> that header file xxx #included header file yyy which contained
> the definition

> typedef struct _XmGadgetRec
> {
>    zzz  rectangle;
>    etc.

> Now, it won't compile, but the error message is at line /* B */

> Is it a compiler bug to NOT complain about line /* C */
> something like "_XmGadgetRec is undefined" ?

Nope, it's perfectly legal to declare an incomplete struct.

Quote:
> Is it a compiler bug to NOT complain about line /* A */
> something like "XmGadget is a variable, not a type" ?

Nope, it's still a type.

Quote:
> (I realize these messages are not cryptic enough for C, but
> you get the idea anyway.)

> If I put #include yyy in our code, am I just covering up a bunch
> of bugs and invited bigger trouble later?

Probably.

It looks like you are violating a spec by using a struct's ``private'' data,
and then they decided to tighten up access to it by hiding the data.  Best
best would be to figure out how to access the data you need through the right
interface.

``typedef struct _XmGadgetRec  * XmGadget;'' is declaring a new type that is a
pointer to an incomplete type, which is legal if all you want to do is
pass/copy pointers.  Obviously, you can't access the fields of the struct.

This is usually done to implement "private" data members within a struct and
minimize compilation dependencies.  The vendor declares a pointer to an
incomplete type.  Their code which implements it defines that type locally.
However, if it expects you, the client, not to muck with the struct's
internals, it can leave out the details of the struct in the public header
file, only leaving the incomplete type.  Thus, you can pass/copy/define
pointers to that struct, but nothing deeper.

You might be able to cheat by grovelling around and including "private" header
file, but it might not be there anymore.  If you are extending Motif and have
a source license, then you should probably find and include the private
stuff.  If not, it's better to find what the proper way is to get the data you
need.

Here's a simple example:

 typedef struct foo *FooStar;

 void gimme_a_foo_star(FooStar have_a_foo_star)
 {
 }

 int main(void)
 {
   foo abad_foo;        /* BZZT */
   FooStar afoostar;    /* fine */
   gimme_a_foo_star(afoostar);
 }

Now, if gimme_a_foo_star() was in a different module, it could fully define
"struct foo" and manipulate its internals, whilst main() cannot.
--



Mon, 18 Mar 2002 03:00:00 GMT  
 Confusing problems with X libraries and headers

Quote:

> Code excerpt:

> void Xmx_Unhighlight_Border (A_Gadget)
>     XmGadget A_Gadget;                  /* A */
> {
>         register int X = A_Gadget->rectangle.x;  /* B */

> Now this code #includes (indirectly) an O.S. vendor's header
> file xxx containing

> typedef struct _XmGadgetRec  * XmGadget;  /* C */

> Doesn't that mean XmGadget is a variable that points to an
> object typedef'd as _XmGadgetRec  ?  But the compiler accepted
> it until.....

> In an O.S. upgrade, the vendor screwed up, and failed to ensure
> that header file xxx #included header file yyy which contained
> the definition

> typedef struct _XmGadgetRec
> {
>    zzz  rectangle;
>    etc.

> Now, it won't compile, but the error message is at line /* B */

> Is it a compiler bug to NOT complain about line /* C */
> something like "_XmGadgetRec is undefined" ?

Nope, the compiler is right.
typedef struct _XmGadgetRec  * XmGadget; says to the compiler:
"There's a structure called _XmGadgetRec.  Trust me.  Whenever
I say XmGadget, I'm actually talking about a pointer to one of
these structures."
The compiler doesn't have to know what the structure looks like
to know what a _pointer_ to the structure looks like.

Quote:

> Is it a compiler bug to NOT complain about line /* A */
> something like "XmGadget is a variable, not a type" ?

Nope.  Line /* B */ defined what XmGadget means.  It's a pointer
to an undescribed struct.

It complains about line /* B */ because this is the first time
that you try to look inside of the mystery structure.  As long
as you don't ask for the contents of the struct, C is happy to
let you use it.

Quote:

> If I put #include yyy in our code, am I just covering up a bunch
> of bugs and invited bigger trouble later?

Depends.  The vendor may have done this intentionally if XmGadgetRec
is meant to be an opaque data structure.  Then you're reaching into
vendore specific structures which the vendor is free to change in
the future.  If, however, it's a genuine bug in the vendor's header
including it yourself isn't likely to cause any harm.

/peter
--



Tue, 19 Mar 2002 03:00:00 GMT  
 
 [ 6 post ] 

 Relevant Pages 

1. Library, header file problem

2. static libraries and precompiled header problems

3. #ifndef/#ifdef problems in my header file (conditional header inclusion)

4. Help with header files and library

5. Public-Key Cryptography Standard library + headers.

6. Headers and libraries

7. Standard Libraries header files.

8. C Libraries, header files etc..

9. header/library files

10. header/library files II

11. What Header Files Comprise the C Standard Library?

12. Both declare standard library functions and include header?

 

 
Powered by phpBB® Forum Software