A
Asbjørn Sæbø
Good afternoon, gentlemen of the C group,
I would appreciate your comments to the following:
The situations is that I have a data type, the details of which I
intended to hide from the users of that module. They have access to
the type definition, and to a number of functions for doing operations
on variables of that type, but they should never try to operate
directly on variables of that type them selves, they should use the
provided function interface.
One of the things we need to do with wariables of this type is to pass
around pointers to them. But as it happens, the type is currently
implemented as an array (the users should not really care, and the
implementation has changed in the past), and that makes creating and
passing pointers to this type somewhat difficult. See example program
below.
So, the question is: Given that I want to hide the details of what
this type is from the users, and that I want pointers to this type to
behave as pointers to "normal" types, what is the best approach?
With kind regards
Asbjørn Sæbø
/* Example program ******************************************************************/
#include <stdint.h>
#define OTHER_OBJECT_SIZE 5
typedef uint8_t object_t; // A "normal" type
typedef uint8_t other_object_t[OTHER_OBJECT_SIZE]; // A type that happens to be an array
/* A function that works on an object of the array type */
void my_func(other_object_t other_object);
void my_func(other_object_t other_object)
{
uint8_t k;
for( k = 0; k < OTHER_OBJECT_SIZE; k++ )
{
other_object[k] = k;
}
}
int main( void )
{
object_t my_object;
object_t * p_object;
other_object_t my_other_object;
other_object_t * p_other_object;
uint8_t * p_uint8_t;
/* Operations on the "normal" object */
// p_object = my_object; // Compiler error, tries to convert uint8_t to pointer
p_object = &my_object; // OK, no warnings
/* Operations on the array object */
p_other_object = my_other_object; // Compiler warning - pointer to different objects
// Lint warning: Type mismatch (unsigned char (*)[5] = unsigned char *)
p_other_object = &my_other_object; // Compiler warning - pointer to different objects
// Lint warning: Suspicious use of &
/* Using a uint8_t pointer to access the array object */
p_uint8_t = my_other_object; // OK to compiler, and to Lint
p_uint8_t = &my_other_object; // OK to compiler
// Lint warning: Type mismatch (unsigned char (*)[5] = unsigned char *)
// Lint warning: Suspicious use of &
p_uint8_t = &my_other_object[0]; // OK to compiler and to Lint
/* Passing a pointer to the array object to a function */
my_func(my_other_object); // OK to compiler and Lint, but hides that we are passing a pointer
my_func(&my_other_object); // Lint warning: Type mismatch (unsigned char (*)[5] = unsigned char *)
// Lint warning: Suspicious use of &
return 0;
}
I would appreciate your comments to the following:
The situations is that I have a data type, the details of which I
intended to hide from the users of that module. They have access to
the type definition, and to a number of functions for doing operations
on variables of that type, but they should never try to operate
directly on variables of that type them selves, they should use the
provided function interface.
One of the things we need to do with wariables of this type is to pass
around pointers to them. But as it happens, the type is currently
implemented as an array (the users should not really care, and the
implementation has changed in the past), and that makes creating and
passing pointers to this type somewhat difficult. See example program
below.
So, the question is: Given that I want to hide the details of what
this type is from the users, and that I want pointers to this type to
behave as pointers to "normal" types, what is the best approach?
With kind regards
Asbjørn Sæbø
/* Example program ******************************************************************/
#include <stdint.h>
#define OTHER_OBJECT_SIZE 5
typedef uint8_t object_t; // A "normal" type
typedef uint8_t other_object_t[OTHER_OBJECT_SIZE]; // A type that happens to be an array
/* A function that works on an object of the array type */
void my_func(other_object_t other_object);
void my_func(other_object_t other_object)
{
uint8_t k;
for( k = 0; k < OTHER_OBJECT_SIZE; k++ )
{
other_object[k] = k;
}
}
int main( void )
{
object_t my_object;
object_t * p_object;
other_object_t my_other_object;
other_object_t * p_other_object;
uint8_t * p_uint8_t;
/* Operations on the "normal" object */
// p_object = my_object; // Compiler error, tries to convert uint8_t to pointer
p_object = &my_object; // OK, no warnings
/* Operations on the array object */
p_other_object = my_other_object; // Compiler warning - pointer to different objects
// Lint warning: Type mismatch (unsigned char (*)[5] = unsigned char *)
p_other_object = &my_other_object; // Compiler warning - pointer to different objects
// Lint warning: Suspicious use of &
/* Using a uint8_t pointer to access the array object */
p_uint8_t = my_other_object; // OK to compiler, and to Lint
p_uint8_t = &my_other_object; // OK to compiler
// Lint warning: Type mismatch (unsigned char (*)[5] = unsigned char *)
// Lint warning: Suspicious use of &
p_uint8_t = &my_other_object[0]; // OK to compiler and to Lint
/* Passing a pointer to the array object to a function */
my_func(my_other_object); // OK to compiler and Lint, but hides that we are passing a pointer
my_func(&my_other_object); // Lint warning: Type mismatch (unsigned char (*)[5] = unsigned char *)
// Lint warning: Suspicious use of &
return 0;
}