RE: Is strongly-typed programming conceivable for C code using gcc ?

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



> Taking Dima's solution in conjunction with the way Apple solved their
> similar problem by using opaque types in Cocoa and Carbon:

Therefore, if I understand you right, the following C source code example has
to be put in a '.h' header file?!
  struct CW_C_MsgUp_s;
  typedef struct CW_C_MsgUp_t* CW_C_MsgUp_t;
  
  struct CW_C_MsgDown_s;
  typedef struct CW_C_MsgDown_t* CW_C_MsgDown_t; 

And the following Dima's struct declaration (completing your example) has to be
written in the '.c' source file?!
  typedef struct CW_C_MsgUp_s {
      void* ptr;
  } CW_C_MsgUp_t;
  
  typedef struct CW_C_MsgDown_s {
     void* ptr;
  } CW_C_MsgDown_t;

Is that true?

> This will insulate your implementation of those opaque types from the public
> header files (note that the structs are forward references, and not declared
> publically), and allow you some measure of type safety in C.
> 
> Apple uses a factory function to create their opaque types, and for most
> opaque types the CFRelease function to destruct them (using a reference
> counting mechanism).  That's the role that CW_C_MsgUp_new() and
> CW_C_MsgDown_new() provides.

Why did you talk about a "reference counting mechanism"? Because in my
implementation my C "constructor" and "destructor" functions do not have any
counting mechanism, is that a problem. Actually, I rely on the users/callers of
the functions to call the "destructor" as many times as the "constructor",
avoiding memory losses.
But, if you talked about a "reference counting mechanism", is it to prevent
memory leaks? By implementing a kind of basic "garbage collector", destroying
undeleted allocated structures? Is that what you meant?

> As far as them being pointers... I believe that you will want them to be
> pointers baked into the typedef. 
> 
> The one change to your code would be to change from this...
> 
> CW_C_MsgUp_t *my_up_msg;
> CW_C_MsgDown_t *my_down_msg;
> 
> ...to this...
> 
> CW_C_MsgUp_t my_up_msg;
> CW_C_MsgDown_t my_down_msg;

Yes and no. Because if it will or will not be confused with such a typedef.
Because my "*_new" and "*_delete" functions will allocate and destroy objects
(structures, classes, int, char buf, etc, who knows, that doesn't matter) and
the allocation function on failure can return a null pointer. Therefore how
will the caller test the returned value (not considered as pointer because of
typedef) with null?
I think a workaround could be to pass the "my_up_msg" or "my_down_msg"
variables as parameter of "*_new" functions and test an integer returned value
of "*_new", telling how everything goes?

Example ;o)

<example1>
  typedef struct CW_C_MsgUp_t* CW_C_MsgUp_t;
  [...]
  CW_C_MsgUp_t my_up_msg;

  my_up_msg = CW_C_MsgUp_new();
  if (my_up_msg == NULL) /* I think gcc will complain, here! */
  {
     return -1;
  }
  [...]
</example1>

<example2>
  typedef struct CW_C_MsgUp_t* CW_C_MsgUp_t;
  [...]
  int rval = 0;

  rval = CW_C_MsgUp_new(&my_up_msg);
  if (rval < 0)
  {
     return -1;
  }
  [...]
</example2>

Which of example1 and example2 is better to use?

On the same kind of reflexion, how do I have to initialize my_up_msg?
  1. my_up_msg = 0;
  2. my_up_msg = null; 
  4. memset(&my_up_msg, 0, sizeof(my_up_msg))?
  3. memset(my_up_msg, 0, sizeof(my_up_msg))? 

The solution I feel is the good one are 2 and 4, but they mean that I do not
avoid the fact that "my_up_msg" is a typedef-ed pointer. Solutions 1 and 3 are
to be used if the user completely avoids the fact that CW_C_MsgUp_t is a
pointer type.

How could I do to not confuse the users and me? I'm aware that this solution is
very interesting because it does not allow people to dereference the variable.
But is that a recommended coding rule?


Thanks a lot for all your help.

Regards.

-- 
Alex.



[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux