const vs typedef

E

Edward Rutherford

I've got an opaque type encapsulated with a typedef, ie

typedef struct my_obj *my_obj_handle;

What I want is to define a function type that takes one of these
handles in such a way that the function cant modify what's pointed to, in
accordance with Data Hiding principals.

If I do something like

my_function(const my_obj_handle H)
{
*H = something;

}

then this will compile OK because the const applies to H not *H!

Also if I swap the const to the right and have my_function(my_obj_handle
const H) then it's still H that's constant and not *H!

How can I define a function like
my_function(const struct my_obj *H)
but using the typedef instead of struct my_obj?
 
J

James Kuyper

I've got an opaque type encapsulated with a typedef, ie

typedef struct my_obj *my_obj_handle;

What I want is to define a function type that takes one of these
handles in such a way that the function cant modify what's pointed to, in
accordance with Data Hiding principals.

If I do something like

my_function(const my_obj_handle H)
{
*H = something;

}

then this will compile OK because the const applies to H not *H!

Also if I swap the const to the right and have my_function(my_obj_handle
const H) then it's still H that's constant and not *H!

How can I define a function like
my_function(const struct my_obj *H)
but using the typedef instead of struct my_obj?

typedef struct my_obj my_obj_handler;

void my_function( const my_obj_handler *H);

This is a prime example of why it's a often a bad idea to use a typedef
to hide the fact that something is a pointer (there's several other
reasons as well). The pointer-ness gets bound into the type name,
preventing 'const' from modifying the pointed-at type; it can only
modify the type of the pointer object itself.
 
J

Jens Thoms Toerring

Edward Rutherford said:
I've got an opaque type encapsulated with a typedef, ie
typedef struct my_obj *my_obj_handle;
What I want is to define a function type that takes one of these
handles in such a way that the function cant modify what's pointed to, in
accordance with Data Hiding principals.
If I do something like
my_function(const my_obj_handle H)
{
*H = something;

then this will compile OK because the const applies to H not *H!

If you insist on using typedefs for pointers (frowned upon
by many people here, and they have their reasons) use two
typedefs, one just like your original one
typedef struct my_obj *my_obj_handle;

and another

typedef const struct my_obj * my_const_obj_handle;

and declare your function to take an argument of the
second type:

void my_function( my_const obj_handle H );

That will keep the function from changing what 'H' is pointing
to as the following simple test program will show when you try
to compile it

----------------8<------------------------------
struct my_obj
{
int a;
};

typedef struct my_obj * my_obj_handle;
typedef const struct my_obj * my_const_obj_handle;

struct my_obj something = { 1 };

void my_function( my_const_obj_handle H )
{
*H = something;
}

int main( void )
{
struct my_obj x;
my_obj_handle y = &x;

my_function( y );
return 1;
}
----------------8<------------------------------
Also if I swap the const to the right and have my_function(my_obj_handle
const H) then it's still H that's constant and not *H!

Yes. You created a new type and that is made constant, not
what it may be pointing to. The way you seem to think about
it is that a typedef is nothing ,ore than a fancy kind of
macro (i.e. a textual replacement command) but that it isn't.

Regards, Jens
 
K

Kaz Kylheku

If you insist on using typedefs for pointers (frowned upon
by many people here, and they have their reasons) use two
typedefs, one just like your original one

The main reason for all this frowning is the cultivation of forehead furrows.
 
J

Jens Thoms Toerring

The main reason for all this frowning is the cultivation of forehead
furrows.

Yes. The number of furrows (and the depth of the ones already
their) on my forehead definitely is in actual danger of in-
creasing when I have to understand code where I can't see at
a glance if something is a pointer or not and have instead to
grep through all kinds of header files or whatever to figure
it out. So while I don't mind having a struct typdef'ed I never
typedef a pointer type - the amount work saved while writing
the program is typically offset (at least for me) by much,
much more boring menal gymnastics when trying to maintain
such stuff later on.
Regards, Jens
 
E

Edward Rutherford

Stefan said:
typedef struct my_obj *my_obj_handle; my_function( const my_obj_handle H
){ *H = *H; }

Error: dereferencing pointer to incomplete type

I think you misunderstood. The function will be implemented inside the
library which will have access to the internals (non-opaque version of
the type). I want the library to be able to give a guarantee to calling
code that it will not modified the passed object.

I would like to absorb the pointer into the typedef if possible. The main
advantage I see is that you get pass-by-reference semantics for free. It
also seems the most common way in popular libraries eg GMP.

Thanks for the replies.

--EPR
 
S

Stefan Ram

Edward Rutherford said:
I think you misunderstood. The function will be implemented inside the
library which will have access to the internals (non-opaque version of
the type). I want the library to be able to give a guarantee to calling
code that it will not modified the passed object.

If the function does not need to read from the struct,
it can be defined outside of the scope of the struct definition
(opaque), while other functions of the same library can be
defined inside of this scope (non-opaque). So it can be
chosen on a per-function base whether the struct can be
accessed.

If the function is to become part of the library which will
have access to the internals, then there is no need for it
to use the »opaque« typedef my_obj_handle. It can use the
non-opaque struct my_obj, which then can be combined with
»const« to give the desired effect.
 
K

Kaz Kylheku

I think you misunderstood. The function will be implemented inside the
library which will have access to the internals (non-opaque version of
the type). I want the library to be able to give a guarantee to calling
code that it will not modified the passed object.

typedef struct my_obj *obj_handle;
typedef const struct my_obj *immutable_obj_handle;
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top