473,883 Members | 1,648 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Opaque pointers

Can anyone explain what's an opaque pointer and how it's implemented in
C?

I read about this concept in the book "C interfaces and
implementations ".

Here's an example from the book (list.h - available from the website):

#define T List_T

typedef struct T *T;
struct T {
T rest;
void *first;
};

extern T List_append (T list, T tail);
extern T List_copy (T list);
extern T List_list (void *x, ...);
..
..
and so on...

It seems the struct behind List_T is now hidden from the application
using these functions.The contents of List_T cannot be accessed (or
dereferenced?).

But I don't see why not. If I have access to the header file, wouldn't
I be able to dereference the contents of the structure? Or am I missing
the meaning of opaque?

Any answers is much appreciated.

Aug 17 '06 #1
18 11337
chankl wrote:
Can anyone explain what's an opaque pointer and how it's implemented in
C?

I read about this concept in the book "C interfaces and
implementations ".

Here's an example from the book (list.h - available from the website):

#define T List_T

typedef struct T *T;
struct T {
T rest;
void *first;
};

extern T List_append (T list, T tail);
extern T List_copy (T list);
extern T List_list (void *x, ...);
.
.
and so on...

It seems the struct behind List_T is now hidden from the application
using these functions.The contents of List_T cannot be accessed (or
dereferenced?).

But I don't see why not. If I have access to the header file, wouldn't
I be able to dereference the contents of the structure? Or am I missing
the meaning of opaque?

Any answers is much appreciated.
In your header file, you'd have something along the lines of:

foo.h
-----
typedef struct foo foo;

foo *create_foo(voi d);
void destroy_foo(foo *ptr);

void use_foo(foo *ptr);

The actual definition of 'struct foo' goes in the source file:

foo.c
-----
struct foo
{
/* ... */
};

So that it's only foo.c that knows what the contents of a struct foo
are. The contents are hidden, ie opaque, from everything that merely
includes foo.h - all you can do is pass pointers around.

--
rh

Aug 17 '06 #2
Richard Harnden wrote:
>
chankl wrote:
Can anyone explain what's an opaque pointer and how it's implemented in
C?

I read about this concept in the book "C interfaces and
implementations ".

Here's an example from the book (list.h - available from the website):

#define T List_T

typedef struct T *T;
struct T {
T rest;
void *first;
};

extern T List_append (T list, T tail);
extern T List_copy (T list);
extern T List_list (void *x, ...);
.
.
and so on...

It seems the struct behind List_T is now hidden from the application
using these functions.The contents of List_T cannot be accessed (or
dereferenced?).

But I don't see why not. If I have access to the header file, wouldn't
I be able to dereference the contents of the structure? Or am I missing
the meaning of opaque?

Any answers is much appreciated.

In your header file, you'd have something along the lines of:

foo.h
-----
typedef struct foo foo;

foo *create_foo(voi d);
void destroy_foo(foo *ptr);

void use_foo(foo *ptr);

The actual definition of 'struct foo' goes in the source file:

foo.c
-----
struct foo
{
/* ... */
};

So that it's only foo.c that knows what the contents of a struct foo
are. The contents are hidden, ie opaque, from everything that merely
includes foo.h - all you can do is pass pointers around.
That's wrong.
The defintion of the stuct type needs to be in the header file.
Otherwise,
void destroy_foo(foo *ptr);
wouldn't mean anything in the header file.

--
pete
Aug 17 '06 #3
pete wrote:
>
Richard Harnden wrote:

chankl wrote:
Can anyone explain what's an opaque pointer and how it's implemented in
C?
>
I read about this concept in the book "C interfaces and
implementations ".
>
Here's an example from the book (list.h - available from the website):
>
#define T List_T
>
typedef struct T *T;
struct T {
T rest;
void *first;
};
>
extern T List_append (T list, T tail);
extern T List_copy (T list);
extern T List_list (void *x, ...);
.
.
and so on...
>
It seems the struct behind List_T is now hidden from the application
using these functions.The contents of List_T cannot be accessed (or
dereferenced?).
>
But I don't see why not. If I have access to the header file, wouldn't
I be able to dereference the contents of the structure? Or am I missing
the meaning of opaque?
>
Any answers is much appreciated.
>
In your header file, you'd have something along the lines of:

foo.h
-----
typedef struct foo foo;

foo *create_foo(voi d);
void destroy_foo(foo *ptr);

void use_foo(foo *ptr);

The actual definition of 'struct foo' goes in the source file:

foo.c
-----
struct foo
{
/* ... */
};

So that it's only foo.c that knows what the contents of a struct foo
are. The contents are hidden, ie opaque, from everything that merely
includes foo.h - all you can do is pass pointers around.

That's wrong.
The defintion of the stuct type needs to be in the header file.
Otherwise,
void destroy_foo(foo *ptr);
wouldn't mean anything in the header file.
In general, it's only object defintions and function definitions
that don't belong in header files.
Typedefs and enums are two kinds of definitions
that are typically OK in header files.

I'm not too familiar with inline functions.
I think they can go in header files too,
but I'm not sure.

--
pete
Aug 17 '06 #4
pete wrote:
Richard Harnden wrote:
>chankl wrote:
>>Can anyone explain what's an opaque pointer and how it's implemented in
C?

I read about this concept in the book "C interfaces and
implementatio ns".

Here's an example from the book (list.h - available from the website):

#define T List_T

typedef struct T *T;
struct T {
T rest;
void *first;
};

extern T List_append (T list, T tail);
extern T List_copy (T list);
extern T List_list (void *x, ...);
.
.
and so on...

It seems the struct behind List_T is now hidden from the application
using these functions.The contents of List_T cannot be accessed (or
dereferenced? ).

But I don't see why not. If I have access to the header file, wouldn't
I be able to dereference the contents of the structure? Or am I missing
the meaning of opaque?

Any answers is much appreciated.
In your header file, you'd have something along the lines of:

foo.h
-----
typedef struct foo foo;

foo *create_foo(voi d);
void destroy_foo(foo *ptr);

void use_foo(foo *ptr);

The actual definition of 'struct foo' goes in the source file:

foo.c
-----
struct foo
{
/* ... */
};

So that it's only foo.c that knows what the contents of a struct foo
are. The contents are hidden, ie opaque, from everything that merely
includes foo.h - all you can do is pass pointers around.

That's wrong.
The defintion of the stuct type needs to be in the header file.
Otherwise,
void destroy_foo(foo *ptr);
wouldn't mean anything in the header file.
Only a forward declaration is needed, so the 'content'
of the struct becomes opaque to users of the implementation
of foo.h

With the above foo.h, I can include it and do
foo *h = create_foo();
use_foo(h);
destroy_foo(h);
Aug 17 '06 #5
"chankl" <ch*******@yaho o.com.sgwrites:
Can anyone explain what's an opaque pointer and how it's implemented in
C?

I read about this concept in the book "C interfaces and
implementations ".

Here's an example from the book (list.h - available from the website):

#define T List_T

typedef struct T *T;
struct T {
T rest;
void *first;
};

extern T List_append (T list, T tail);
extern T List_copy (T list);
extern T List_list (void *x, ...);
.
.
and so on...
Ugh. Is that really the code from the book?

I can't think of any good reason for the macro defining T as List_T.
It just obfuscates the code.

Furthermore, it uses the same identifier, T (um, I mean List_T) as the
tag for the struct and as a typedef for a *pointer* to the same
struct. So "struct T" is a structure, and "T" is a pointer to that
same structure.
It seems the struct behind List_T is now hidden from the application
using these functions.The contents of List_T cannot be accessed (or
dereferenced?).

But I don't see why not. If I have access to the header file, wouldn't
I be able to dereference the contents of the structure? Or am I missing
the meaning of opaque?
Yes, any code that includes that header can access the members of the
structure.

If you really want to declare an abstract pointer type, you can make
it point to an *incomplete* structure type:

typedef struct hidden *abstract_point er;

and hide the actual definition of "struct hidden" inside a source file
that implements the library.

You can do this if you want to make it impossible for client code to
see the innards of your structure. An alternative is to put the
structure definition in the visible header, and just tell clients not
to use it. A good example of this is the type FILE in <stdio.h>; the
documented interface just uses FILE* as an abstract pointer type, but
client code *could* access the members of the type FILE. In practice,
this isn't a problem.

Here's a small example of a library declaring an abstract pointer type
and hiding the pointed-to type inside the implementation. There are
three source files, lib.h, lib.c, and main.c.

Note that this declares a typedef for a pointer type, which is
*usually* a bad idea. In this case, the client code doesn't make use
of the fact that it's a pointer. An alternative would be to declare a
typedef for the hidden struct type, and have the code use an explicit
pointer type. (It wouldn't be able to declare an object of the
structure type, since it's incomplete.)

=============== lib.h ===============
#ifndef LIB_H
#define LIB_H

typedef struct ap_hidden *abstract_point er;

abstract_pointe r ap_create (char *s);
char *ap_get (abstract_point er x);
void ap_destroy (abstract_point er x);

#endif
=============== =============== ==========

=============== lib.c ===============
#include "lib.h"
#include <string.h>
#include <stdlib.h>

struct ap_hidden {
char *str;
};

abstract_pointe r ap_create(char *s)
{
struct ap_hidden *const p = malloc(sizeof *p);
const size_t size = strlen(s) + 1;
if (p == NULL) {
return p;
}
p->str = malloc(size);
if (p->str == NULL) {
free(p);
return NULL;
}
strcpy(p->str, s);
return p;
}

char *ap_get(abstrac t_pointer x)
{
return x->str;
}

void ap_destroy(abst ract_pointer x)
{
if (x == NULL) {
return;
}
free(x->str);
free(x);
}
=============== =============== ==========

=============== main.c ===============
#include "lib.h"
#include <stdio.h>

int main(void)
{
abstract_pointe r x = ap_create("Hell o, world");
if (x == NULL) {
printf("ap_crea te() failed\n");
}
else {
printf("ap_crea te() ok, ap_get(x) --\"%s\"\n", ap_get(x));
}
ap_destroy(x);
return 0;
}
=============== =============== ==========

--
Keith Thompson (The_Other_Keit h) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Aug 17 '06 #6
chankl wrote:
Can anyone explain what's an opaque pointer and how it's implemented
in C?

I read about this concept in the book "C interfaces and
implementations ".

Here's an example from the book (list.h - available from the website):

#define T List_T

typedef struct T *T;
struct T {
T rest;
void *first;
};

extern T List_append (T list, T tail);
extern T List_copy (T list);
extern T List_list (void *x, ...);
.
.
and so on...

It seems the struct behind List_T is now hidden from the application
using these functions.The contents of List_T cannot be accessed (or
dereferenced?).

But I don't see why not. If I have access to the header file, wouldn't
I be able to dereference the contents of the structure? Or am I
missing the meaning of opaque?

Any answers is much appreciated.
I seem to remember that Chris Torek had plenty to say on this relatively
recently [and see his 'previously' too]. So, I'd advise you to search the
whole of c.l.c for Chris' stuff [always valuable] - Google's you best mate
here.

--
==============
*Not a pedant*
==============
Aug 17 '06 #7
"Nils O. Selåsdal" wrote:
>
pete wrote:
Richard Harnden wrote:
chankl wrote:
Can anyone explain what's an opaque pointer and how it's implemented in
C?

I read about this concept in the book "C interfaces and
implementation s".

Here's an example from the book (list.h - available from the website):

#define T List_T

typedef struct T *T;
struct T {
T rest;
void *first;
};

extern T List_append (T list, T tail);
extern T List_copy (T list);
extern T List_list (void *x, ...);
.
.
and so on...

It seems the struct behind List_T is now hidden from the application
using these functions.The contents of List_T cannot be accessed (or
dereferenced?) .

But I don't see why not. If I have access to the header file, wouldn't
I be able to dereference the contents of the structure? Or am I missing
the meaning of opaque?

Any answers is much appreciated.

In your header file, you'd have something along the lines of:

foo.h
-----
typedef struct foo foo;

foo *create_foo(voi d);
void destroy_foo(foo *ptr);

void use_foo(foo *ptr);

The actual definition of 'struct foo' goes in the source file:

foo.c
-----
struct foo
{
/* ... */
};

So that it's only foo.c
that knows what the contents of a struct foo
are. The contents are hidden, ie opaque,
from everything that merely
includes foo.h - all you can do is pass pointers around.
That's wrong.
The defintion of the stuct type needs to be in the header file.
Otherwise,
void destroy_foo(foo *ptr);
wouldn't mean anything in the header file.
Only a forward declaration is needed, so the 'content'
of the struct becomes opaque to users of the implementation
of foo.h

With the above foo.h, I can include it and do
foo *h = create_foo();
use_foo(h);
destroy_foo(h);
Thank you.
I hadn't noticed the typedef line:

typedef struct foo foo;

--
pete
Aug 18 '06 #8

chankl wrote:
Can anyone explain what's an opaque pointer and how it's implemented in
C?

I read about this concept in the book "C interfaces and
implementations ".

Here's an example from the book (list.h - available from the website):

#define T List_T

typedef struct T *T;
struct T {
T rest;
void *first;
};

extern T List_append (T list, T tail);
extern T List_copy (T list);
extern T List_list (void *x, ...);
.
.
and so on...

It seems the struct behind List_T is now hidden from the application
using these functions.The contents of List_T cannot be accessed (or
dereferenced?).

But I don't see why not. If I have access to the header file, wouldn't
I be able to dereference the contents of the structure? Or am I missing
the meaning of opaque?

Any answers is much appreciated.
There are actually several different questions in here.

One question is about how C works. If you can #include
the header file, then yes you can indeed dereference
pointers and access structure members.

Another question is about what "opaque type" means. Here
there isn't a single answer, because the term is used in
two similar but slightly different ways -

1. a type whose representation should not be accessed
outside the implementing module

2. a type whose representation can not be accessed outside
the implementing module

Obviously these two usages are related but they are
different, and that's probably the source of the confusion
here.

A third question is, how would one get an #2-style opaque
type in C. The answer there is to put only a declaration
in the header file, and define the struct in a .c file,
as for example -

/* list.h */
...
typedef struct List_struct *List;

extern List List_append(Lis t list, List tail);
extern List List_copy(List list);
extern List List_list(void *x, ...);
...
/* list.c */
#include "list.h"

struct List_struct {
List rest;
void *first;
}

In either case the intention is that only list.c will
access the structure members, but now other code can't
access them because of where the struct itself is defined.

Note that this approach doesn't work if list.h needs to
define macros that access some structure members. In
that case we might still call List an "opaque type",
only now the meaning is more like the first meaning of
opaque type, because C doesn't have a way to allow
macro access but prevent other access.

Aug 18 '06 #9
chankl wrote:
Can anyone explain what's an opaque pointer and how it's implemented in
C?
The other answers given are failrly reasonable. However, I would just
like to point out that opacity is generally focused on the undetailed
struct, and not the fact that it has been typedefed to a pointer.
I.e., the typedef struct List_T * List_T line is redundant and
unnecessary (and also going to cause C++ compilers to go into fits.)
You can simply use the expression struct List_T * instead of List_T
with no ill effect.

I.e., the pointers are derivative of the overall idea of making opaque
structs, and the additional typedef is not relevant to the opacity.

The reason I am pointing this out is that there is an alternative way
to gaining opacity through straight void * pointers. You might accept
void * pointers as your ADT handle, and simply cast it to a (struct
List_T *) inside your implementation. This works just fine, but has
the disadvantage of losing typesafety (the compiler will not warn you
when you've mixed up the handles to two different ADTs, if you declare
them both as void *, for example.) The advantage of using void *, is
that you can support a primitive kind of runtime polymorphism. I.e.,
its possible to have an array of void *'s each pointing to a different
kind of abstract data type, where even this signature can change at
runtime. Obviously in this case, the details of how exactly you would
even know what the type of each entry in such an array is what would be
interesting. This is *probably* beyond what you are interested in at
this moment, but I just thought I should point it out, since your
question was about opaque *pointers*.

--
Paul Hsieh
http://www.pobox.com/~qed/
http://bstring.sf.net/

Aug 19 '06 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

12
4737
by: Ellarco | last post by:
``Opaque-pointer representing the ID of an object. struct _objID; typedef struct _objID * objectID;'' Hi again. Im using an api that defines an objectID type. The above represents the extent of the documentation on it. The above means that objectID is defined as a pointer to an as yet undefined class/struct _objID, and, if I understand the term correctly, is opaque in
19
1582
by: Capstar | last post by:
Hi NG, I've read some time ago in this NG, that when you're writing a library it can be good practice to use an opaque type to point to your structures if the user doesn't need to modify the structure himself. This way the internal structure of the lib can be changed, and the lib can be recompiled, but the application using the lib doesn't need to be recompiled. But then there are two ways to define the opque type:
2
5314
by: Kurt Ng | last post by:
Hi, y'all. Can anyone help me on this problem? I'm working with a third-party C dll, and I'm having trouble importing into C# the dll's methods that return one of the dll's defined types, which are all defined as opaque pointers. What I tried to do is use IntPtr for the opaque pointer return type, but there seems to be a resulting signature problem.
2
1969
by: jashugun | last post by:
Hello to everybody, I'm trying to write a small program which is meant to interact with an sqlite database. My idea is to create once a database handler, which happens to be an opaque pointer (a pointer to a struct which is not defined anywhere, if I understood correctly). Now, if I had the possibility of instantiating a concrete struct, I would create a function like this: struct sqlite& myDb() {
3
2174
by: Ernesto Bascón | last post by:
Hi everybody: I have two questions: 1. I'm using opaque pointers in my classes to hide their data structures; there is a way to use opaque pointers in template classes; since the implementation and the declaration of the template class is in the same file, the use of opaque pointers does not make sense, but... what about implementation hiding for libraries? how can I make sure that the new versions of my libraries have binary...
27
2537
by: Nate Eldredge | last post by:
Consider the following pseudo-code: #include <opaque.h> struct foo { int a; opaque_t op; int b; };
0
10734
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
10836
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
10407
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
9564
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
7960
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
5793
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
5982
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
4606
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
3
3230
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.