Hiding internal type in C without memmory alocation

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP











up vote
7
down vote

favorite
1












I'm developing a library and I want to hide the internal type from the user.



I have something like.

foo.h



typedef struct public

uint16 a;
//...
unsigned char internals[4];
public_type;


foo.c



typedef struct public

uint32_t a;
internals_type;


Then in the functions, I'm doing a cast like.



void bar(public_type * const public_struct)

internals_type* const internals = &public_struct->internals;
intrnals->a = getSomething();
// .....



Is there a better way of doing this?

I've tried some weird stuff with unions and pointers in the header but nothing seems to be better and I'm curious if this can get any cleaner or at least if the warnings from casting a pointer from one type to pointer to another could be removed.



Edit:
I Forgot to mention that the API should be used in a multithread environment and the whole memory should be on the user side. Also, let say that I cannot use dynamic memory allocation.










share|improve this question























  • Possible duplicate of Partitioning struct into private and public sections?
    – Sander De Dycker
    1 hour ago










  • Related questions include Expose only required information without including unnecessary header files, Is there a way to make GCC/Clang aware of inheritance in C?, and…
    – Eric Postpischil
    11 mins ago











  • … Is incompatible pointer assign necessary to implement polymorphism in C.
    – Eric Postpischil
    11 mins ago











  • I was about to close this as a duplicate of one of those, but the new requirements for allocation on the user wide without dynamic memory allocation change it. Those are abnormally restrictive. (They also contrast with the sample code getSomething()—a function cannot return a non-static object if it cannot dynamically allocate memory for it. getSomething would have to return a structure by value.)
    – Eric Postpischil
    8 mins ago











  • @EricPostpischil, In this case, it returns an uint32_t which is a primitive type and it is copied. Since the type of internals_type.a is uint32_t.
    – Petar Velev
    6 mins ago















up vote
7
down vote

favorite
1












I'm developing a library and I want to hide the internal type from the user.



I have something like.

foo.h



typedef struct public

uint16 a;
//...
unsigned char internals[4];
public_type;


foo.c



typedef struct public

uint32_t a;
internals_type;


Then in the functions, I'm doing a cast like.



void bar(public_type * const public_struct)

internals_type* const internals = &public_struct->internals;
intrnals->a = getSomething();
// .....



Is there a better way of doing this?

I've tried some weird stuff with unions and pointers in the header but nothing seems to be better and I'm curious if this can get any cleaner or at least if the warnings from casting a pointer from one type to pointer to another could be removed.



Edit:
I Forgot to mention that the API should be used in a multithread environment and the whole memory should be on the user side. Also, let say that I cannot use dynamic memory allocation.










share|improve this question























  • Possible duplicate of Partitioning struct into private and public sections?
    – Sander De Dycker
    1 hour ago










  • Related questions include Expose only required information without including unnecessary header files, Is there a way to make GCC/Clang aware of inheritance in C?, and…
    – Eric Postpischil
    11 mins ago











  • … Is incompatible pointer assign necessary to implement polymorphism in C.
    – Eric Postpischil
    11 mins ago











  • I was about to close this as a duplicate of one of those, but the new requirements for allocation on the user wide without dynamic memory allocation change it. Those are abnormally restrictive. (They also contrast with the sample code getSomething()—a function cannot return a non-static object if it cannot dynamically allocate memory for it. getSomething would have to return a structure by value.)
    – Eric Postpischil
    8 mins ago











  • @EricPostpischil, In this case, it returns an uint32_t which is a primitive type and it is copied. Since the type of internals_type.a is uint32_t.
    – Petar Velev
    6 mins ago













up vote
7
down vote

favorite
1









up vote
7
down vote

favorite
1






1





I'm developing a library and I want to hide the internal type from the user.



I have something like.

foo.h



typedef struct public

uint16 a;
//...
unsigned char internals[4];
public_type;


foo.c



typedef struct public

uint32_t a;
internals_type;


Then in the functions, I'm doing a cast like.



void bar(public_type * const public_struct)

internals_type* const internals = &public_struct->internals;
intrnals->a = getSomething();
// .....



Is there a better way of doing this?

I've tried some weird stuff with unions and pointers in the header but nothing seems to be better and I'm curious if this can get any cleaner or at least if the warnings from casting a pointer from one type to pointer to another could be removed.



Edit:
I Forgot to mention that the API should be used in a multithread environment and the whole memory should be on the user side. Also, let say that I cannot use dynamic memory allocation.










share|improve this question















I'm developing a library and I want to hide the internal type from the user.



I have something like.

foo.h



typedef struct public

uint16 a;
//...
unsigned char internals[4];
public_type;


foo.c



typedef struct public

uint32_t a;
internals_type;


Then in the functions, I'm doing a cast like.



void bar(public_type * const public_struct)

internals_type* const internals = &public_struct->internals;
intrnals->a = getSomething();
// .....



Is there a better way of doing this?

I've tried some weird stuff with unions and pointers in the header but nothing seems to be better and I'm curious if this can get any cleaner or at least if the warnings from casting a pointer from one type to pointer to another could be removed.



Edit:
I Forgot to mention that the API should be used in a multithread environment and the whole memory should be on the user side. Also, let say that I cannot use dynamic memory allocation.







c embedded






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited 3 mins ago

























asked 1 hour ago









Petar Velev

1,209517




1,209517











  • Possible duplicate of Partitioning struct into private and public sections?
    – Sander De Dycker
    1 hour ago










  • Related questions include Expose only required information without including unnecessary header files, Is there a way to make GCC/Clang aware of inheritance in C?, and…
    – Eric Postpischil
    11 mins ago











  • … Is incompatible pointer assign necessary to implement polymorphism in C.
    – Eric Postpischil
    11 mins ago











  • I was about to close this as a duplicate of one of those, but the new requirements for allocation on the user wide without dynamic memory allocation change it. Those are abnormally restrictive. (They also contrast with the sample code getSomething()—a function cannot return a non-static object if it cannot dynamically allocate memory for it. getSomething would have to return a structure by value.)
    – Eric Postpischil
    8 mins ago











  • @EricPostpischil, In this case, it returns an uint32_t which is a primitive type and it is copied. Since the type of internals_type.a is uint32_t.
    – Petar Velev
    6 mins ago

















  • Possible duplicate of Partitioning struct into private and public sections?
    – Sander De Dycker
    1 hour ago










  • Related questions include Expose only required information without including unnecessary header files, Is there a way to make GCC/Clang aware of inheritance in C?, and…
    – Eric Postpischil
    11 mins ago











  • … Is incompatible pointer assign necessary to implement polymorphism in C.
    – Eric Postpischil
    11 mins ago











  • I was about to close this as a duplicate of one of those, but the new requirements for allocation on the user wide without dynamic memory allocation change it. Those are abnormally restrictive. (They also contrast with the sample code getSomething()—a function cannot return a non-static object if it cannot dynamically allocate memory for it. getSomething would have to return a structure by value.)
    – Eric Postpischil
    8 mins ago











  • @EricPostpischil, In this case, it returns an uint32_t which is a primitive type and it is copied. Since the type of internals_type.a is uint32_t.
    – Petar Velev
    6 mins ago
















Possible duplicate of Partitioning struct into private and public sections?
– Sander De Dycker
1 hour ago




Possible duplicate of Partitioning struct into private and public sections?
– Sander De Dycker
1 hour ago












Related questions include Expose only required information without including unnecessary header files, Is there a way to make GCC/Clang aware of inheritance in C?, and…
– Eric Postpischil
11 mins ago





Related questions include Expose only required information without including unnecessary header files, Is there a way to make GCC/Clang aware of inheritance in C?, and…
– Eric Postpischil
11 mins ago













… Is incompatible pointer assign necessary to implement polymorphism in C.
– Eric Postpischil
11 mins ago





… Is incompatible pointer assign necessary to implement polymorphism in C.
– Eric Postpischil
11 mins ago













I was about to close this as a duplicate of one of those, but the new requirements for allocation on the user wide without dynamic memory allocation change it. Those are abnormally restrictive. (They also contrast with the sample code getSomething()—a function cannot return a non-static object if it cannot dynamically allocate memory for it. getSomething would have to return a structure by value.)
– Eric Postpischil
8 mins ago





I was about to close this as a duplicate of one of those, but the new requirements for allocation on the user wide without dynamic memory allocation change it. Those are abnormally restrictive. (They also contrast with the sample code getSomething()—a function cannot return a non-static object if it cannot dynamically allocate memory for it. getSomething would have to return a structure by value.)
– Eric Postpischil
8 mins ago













@EricPostpischil, In this case, it returns an uint32_t which is a primitive type and it is copied. Since the type of internals_type.a is uint32_t.
– Petar Velev
6 mins ago





@EricPostpischil, In this case, it returns an uint32_t which is a primitive type and it is copied. Since the type of internals_type.a is uint32_t.
– Petar Velev
6 mins ago













3 Answers
3






active

oldest

votes

















up vote
14
down vote













I suggest you read more about opaque data types, and consider e.g. the FILE structure.



In short, don't split your structure into "public" and "private" variants (that way lies madness and possible undefined behavior). Instead just declare a structure in a public header file, and have your functions return pointers to that structure or accept arguments that are pointers to that structure.



Then internally in the library you have a private header file which have the definition of the structure, and use that header file for your implementation.




Simple example



Public header file



#ifndef PUBLIC_HEADER_FILE_H
#define PUBLIC_HEADER_FILE_H

typedef my_private_structure MY_PUBLIC_TYPE;

MY_PUBLIC_TYPE *mylib_create(void);
void mylib_destroy(MY_PUBLIC_TYPE *ptr);

#endif


Private header file



#ifndef PRIVATE_HEADER_FILE_H
#define PRIVATE_HEADER_FILE_H

#include "public_header_file.h"

struct my_private_structure

// Some private fields here
;

#endif


Private library source file



#include "private_header_file.h"
#include <stdlib.h>

MY_PUBLIC_TYPE *mylib_create(void)

MY_PUBLIC_TYPE *ptr = malloc(sizeof *ptr);
return ptr;


void mylib_destroy(MY_PUBLIC_TYPE *ptr)

free(ptr);



You distribute public_header_file.h together with your library. It's the header file that the users of the library will use.



The source of your library, and especially the private_header_file.h file should not be distributed, or at least not installed if you make an open-source library.



Note that this scheme make all of the structure "private", which is usually a good idea since then you can modify it as you like without the users of the library needing to rebuild their applications using your library. To access members of the private structure you can use functions which simply returns the value of whatever member needs to be accessed.






share|improve this answer






















  • Can you add example code? What goes in .h and what in .c
    – Swanand
    1 hour ago










  • @Swanand Okay, done.
    – Some programmer dude
    52 mins ago










  • That's a great answer. Unfortunately, I forgot to mention that there is a restriction of using dynamic memory allocation since the software is low level and should obey some safety principles. I did some edits.
    – Petar Velev
    20 mins ago






  • 1




    @PetarVelev The dynamic allocation is just an example. You could just as well return a pointer to a compile-time allocated object (a static global variable for example). The basic principles stays the same.
    – Some programmer dude
    15 mins ago






  • 1




    @PetarVelev, another solution is to just export the type definitions (so no abstraction hiding) and rely on the user not using the definitions. That will allow the user to allocate an object of the corect size that it can pass to your library functions. So the complete type definition export allows the allocation by the user.
    – Paul Ogilvie
    2 mins ago


















up vote
3
down vote













Typically you use void* to hide your implementation, e.g.



void *create_foo(int param1, int param2);
void print_foo(void* foo);
int operate_on_foo(void* foo);


So you "cast" the void* in your functions to your internal type.



The downside of this is, that the compiler can't help you with the types, e.g. the user of the library can use a int* and pass it to your function and the compiler will accept it. When you use an actual type, the compiler will complain.






share|improve this answer



























    up vote
    2
    down vote













    You can do in foo.h:



    typedef struct internals_type;
    typedef struct
    uint16 a;
    internals_type* internals;
    public_type


    Including foo.h is then enough for your user to compile, without knowing what is exactly inside internals_type.






    share|improve this answer






















    • Yes, you're right!
      – Ludo
      1 hour ago










    Your Answer





    StackExchange.ifUsing("editor", function ()
    StackExchange.using("externalEditor", function ()
    StackExchange.using("snippets", function ()
    StackExchange.snippets.init();
    );
    );
    , "code-snippets");

    StackExchange.ready(function()
    var channelOptions =
    tags: "".split(" "),
    id: "1"
    ;
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function()
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled)
    StackExchange.using("snippets", function()
    createEditor();
    );

    else
    createEditor();

    );

    function createEditor()
    StackExchange.prepareEditor(
    heartbeatType: 'answer',
    convertImagesToLinks: true,
    noModals: false,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    );



    );













     

    draft saved


    draft discarded


















    StackExchange.ready(
    function ()
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f52835726%2fhiding-internal-type-in-c-without-memmory-alocation%23new-answer', 'question_page');

    );

    Post as a guest






























    3 Answers
    3






    active

    oldest

    votes








    3 Answers
    3






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes








    up vote
    14
    down vote













    I suggest you read more about opaque data types, and consider e.g. the FILE structure.



    In short, don't split your structure into "public" and "private" variants (that way lies madness and possible undefined behavior). Instead just declare a structure in a public header file, and have your functions return pointers to that structure or accept arguments that are pointers to that structure.



    Then internally in the library you have a private header file which have the definition of the structure, and use that header file for your implementation.




    Simple example



    Public header file



    #ifndef PUBLIC_HEADER_FILE_H
    #define PUBLIC_HEADER_FILE_H

    typedef my_private_structure MY_PUBLIC_TYPE;

    MY_PUBLIC_TYPE *mylib_create(void);
    void mylib_destroy(MY_PUBLIC_TYPE *ptr);

    #endif


    Private header file



    #ifndef PRIVATE_HEADER_FILE_H
    #define PRIVATE_HEADER_FILE_H

    #include "public_header_file.h"

    struct my_private_structure

    // Some private fields here
    ;

    #endif


    Private library source file



    #include "private_header_file.h"
    #include <stdlib.h>

    MY_PUBLIC_TYPE *mylib_create(void)

    MY_PUBLIC_TYPE *ptr = malloc(sizeof *ptr);
    return ptr;


    void mylib_destroy(MY_PUBLIC_TYPE *ptr)

    free(ptr);



    You distribute public_header_file.h together with your library. It's the header file that the users of the library will use.



    The source of your library, and especially the private_header_file.h file should not be distributed, or at least not installed if you make an open-source library.



    Note that this scheme make all of the structure "private", which is usually a good idea since then you can modify it as you like without the users of the library needing to rebuild their applications using your library. To access members of the private structure you can use functions which simply returns the value of whatever member needs to be accessed.






    share|improve this answer






















    • Can you add example code? What goes in .h and what in .c
      – Swanand
      1 hour ago










    • @Swanand Okay, done.
      – Some programmer dude
      52 mins ago










    • That's a great answer. Unfortunately, I forgot to mention that there is a restriction of using dynamic memory allocation since the software is low level and should obey some safety principles. I did some edits.
      – Petar Velev
      20 mins ago






    • 1




      @PetarVelev The dynamic allocation is just an example. You could just as well return a pointer to a compile-time allocated object (a static global variable for example). The basic principles stays the same.
      – Some programmer dude
      15 mins ago






    • 1




      @PetarVelev, another solution is to just export the type definitions (so no abstraction hiding) and rely on the user not using the definitions. That will allow the user to allocate an object of the corect size that it can pass to your library functions. So the complete type definition export allows the allocation by the user.
      – Paul Ogilvie
      2 mins ago















    up vote
    14
    down vote













    I suggest you read more about opaque data types, and consider e.g. the FILE structure.



    In short, don't split your structure into "public" and "private" variants (that way lies madness and possible undefined behavior). Instead just declare a structure in a public header file, and have your functions return pointers to that structure or accept arguments that are pointers to that structure.



    Then internally in the library you have a private header file which have the definition of the structure, and use that header file for your implementation.




    Simple example



    Public header file



    #ifndef PUBLIC_HEADER_FILE_H
    #define PUBLIC_HEADER_FILE_H

    typedef my_private_structure MY_PUBLIC_TYPE;

    MY_PUBLIC_TYPE *mylib_create(void);
    void mylib_destroy(MY_PUBLIC_TYPE *ptr);

    #endif


    Private header file



    #ifndef PRIVATE_HEADER_FILE_H
    #define PRIVATE_HEADER_FILE_H

    #include "public_header_file.h"

    struct my_private_structure

    // Some private fields here
    ;

    #endif


    Private library source file



    #include "private_header_file.h"
    #include <stdlib.h>

    MY_PUBLIC_TYPE *mylib_create(void)

    MY_PUBLIC_TYPE *ptr = malloc(sizeof *ptr);
    return ptr;


    void mylib_destroy(MY_PUBLIC_TYPE *ptr)

    free(ptr);



    You distribute public_header_file.h together with your library. It's the header file that the users of the library will use.



    The source of your library, and especially the private_header_file.h file should not be distributed, or at least not installed if you make an open-source library.



    Note that this scheme make all of the structure "private", which is usually a good idea since then you can modify it as you like without the users of the library needing to rebuild their applications using your library. To access members of the private structure you can use functions which simply returns the value of whatever member needs to be accessed.






    share|improve this answer






















    • Can you add example code? What goes in .h and what in .c
      – Swanand
      1 hour ago










    • @Swanand Okay, done.
      – Some programmer dude
      52 mins ago










    • That's a great answer. Unfortunately, I forgot to mention that there is a restriction of using dynamic memory allocation since the software is low level and should obey some safety principles. I did some edits.
      – Petar Velev
      20 mins ago






    • 1




      @PetarVelev The dynamic allocation is just an example. You could just as well return a pointer to a compile-time allocated object (a static global variable for example). The basic principles stays the same.
      – Some programmer dude
      15 mins ago






    • 1




      @PetarVelev, another solution is to just export the type definitions (so no abstraction hiding) and rely on the user not using the definitions. That will allow the user to allocate an object of the corect size that it can pass to your library functions. So the complete type definition export allows the allocation by the user.
      – Paul Ogilvie
      2 mins ago













    up vote
    14
    down vote










    up vote
    14
    down vote









    I suggest you read more about opaque data types, and consider e.g. the FILE structure.



    In short, don't split your structure into "public" and "private" variants (that way lies madness and possible undefined behavior). Instead just declare a structure in a public header file, and have your functions return pointers to that structure or accept arguments that are pointers to that structure.



    Then internally in the library you have a private header file which have the definition of the structure, and use that header file for your implementation.




    Simple example



    Public header file



    #ifndef PUBLIC_HEADER_FILE_H
    #define PUBLIC_HEADER_FILE_H

    typedef my_private_structure MY_PUBLIC_TYPE;

    MY_PUBLIC_TYPE *mylib_create(void);
    void mylib_destroy(MY_PUBLIC_TYPE *ptr);

    #endif


    Private header file



    #ifndef PRIVATE_HEADER_FILE_H
    #define PRIVATE_HEADER_FILE_H

    #include "public_header_file.h"

    struct my_private_structure

    // Some private fields here
    ;

    #endif


    Private library source file



    #include "private_header_file.h"
    #include <stdlib.h>

    MY_PUBLIC_TYPE *mylib_create(void)

    MY_PUBLIC_TYPE *ptr = malloc(sizeof *ptr);
    return ptr;


    void mylib_destroy(MY_PUBLIC_TYPE *ptr)

    free(ptr);



    You distribute public_header_file.h together with your library. It's the header file that the users of the library will use.



    The source of your library, and especially the private_header_file.h file should not be distributed, or at least not installed if you make an open-source library.



    Note that this scheme make all of the structure "private", which is usually a good idea since then you can modify it as you like without the users of the library needing to rebuild their applications using your library. To access members of the private structure you can use functions which simply returns the value of whatever member needs to be accessed.






    share|improve this answer














    I suggest you read more about opaque data types, and consider e.g. the FILE structure.



    In short, don't split your structure into "public" and "private" variants (that way lies madness and possible undefined behavior). Instead just declare a structure in a public header file, and have your functions return pointers to that structure or accept arguments that are pointers to that structure.



    Then internally in the library you have a private header file which have the definition of the structure, and use that header file for your implementation.




    Simple example



    Public header file



    #ifndef PUBLIC_HEADER_FILE_H
    #define PUBLIC_HEADER_FILE_H

    typedef my_private_structure MY_PUBLIC_TYPE;

    MY_PUBLIC_TYPE *mylib_create(void);
    void mylib_destroy(MY_PUBLIC_TYPE *ptr);

    #endif


    Private header file



    #ifndef PRIVATE_HEADER_FILE_H
    #define PRIVATE_HEADER_FILE_H

    #include "public_header_file.h"

    struct my_private_structure

    // Some private fields here
    ;

    #endif


    Private library source file



    #include "private_header_file.h"
    #include <stdlib.h>

    MY_PUBLIC_TYPE *mylib_create(void)

    MY_PUBLIC_TYPE *ptr = malloc(sizeof *ptr);
    return ptr;


    void mylib_destroy(MY_PUBLIC_TYPE *ptr)

    free(ptr);



    You distribute public_header_file.h together with your library. It's the header file that the users of the library will use.



    The source of your library, and especially the private_header_file.h file should not be distributed, or at least not installed if you make an open-source library.



    Note that this scheme make all of the structure "private", which is usually a good idea since then you can modify it as you like without the users of the library needing to rebuild their applications using your library. To access members of the private structure you can use functions which simply returns the value of whatever member needs to be accessed.







    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited 16 mins ago

























    answered 1 hour ago









    Some programmer dude

    286k24233393




    286k24233393











    • Can you add example code? What goes in .h and what in .c
      – Swanand
      1 hour ago










    • @Swanand Okay, done.
      – Some programmer dude
      52 mins ago










    • That's a great answer. Unfortunately, I forgot to mention that there is a restriction of using dynamic memory allocation since the software is low level and should obey some safety principles. I did some edits.
      – Petar Velev
      20 mins ago






    • 1




      @PetarVelev The dynamic allocation is just an example. You could just as well return a pointer to a compile-time allocated object (a static global variable for example). The basic principles stays the same.
      – Some programmer dude
      15 mins ago






    • 1




      @PetarVelev, another solution is to just export the type definitions (so no abstraction hiding) and rely on the user not using the definitions. That will allow the user to allocate an object of the corect size that it can pass to your library functions. So the complete type definition export allows the allocation by the user.
      – Paul Ogilvie
      2 mins ago

















    • Can you add example code? What goes in .h and what in .c
      – Swanand
      1 hour ago










    • @Swanand Okay, done.
      – Some programmer dude
      52 mins ago










    • That's a great answer. Unfortunately, I forgot to mention that there is a restriction of using dynamic memory allocation since the software is low level and should obey some safety principles. I did some edits.
      – Petar Velev
      20 mins ago






    • 1




      @PetarVelev The dynamic allocation is just an example. You could just as well return a pointer to a compile-time allocated object (a static global variable for example). The basic principles stays the same.
      – Some programmer dude
      15 mins ago






    • 1




      @PetarVelev, another solution is to just export the type definitions (so no abstraction hiding) and rely on the user not using the definitions. That will allow the user to allocate an object of the corect size that it can pass to your library functions. So the complete type definition export allows the allocation by the user.
      – Paul Ogilvie
      2 mins ago
















    Can you add example code? What goes in .h and what in .c
    – Swanand
    1 hour ago




    Can you add example code? What goes in .h and what in .c
    – Swanand
    1 hour ago












    @Swanand Okay, done.
    – Some programmer dude
    52 mins ago




    @Swanand Okay, done.
    – Some programmer dude
    52 mins ago












    That's a great answer. Unfortunately, I forgot to mention that there is a restriction of using dynamic memory allocation since the software is low level and should obey some safety principles. I did some edits.
    – Petar Velev
    20 mins ago




    That's a great answer. Unfortunately, I forgot to mention that there is a restriction of using dynamic memory allocation since the software is low level and should obey some safety principles. I did some edits.
    – Petar Velev
    20 mins ago




    1




    1




    @PetarVelev The dynamic allocation is just an example. You could just as well return a pointer to a compile-time allocated object (a static global variable for example). The basic principles stays the same.
    – Some programmer dude
    15 mins ago




    @PetarVelev The dynamic allocation is just an example. You could just as well return a pointer to a compile-time allocated object (a static global variable for example). The basic principles stays the same.
    – Some programmer dude
    15 mins ago




    1




    1




    @PetarVelev, another solution is to just export the type definitions (so no abstraction hiding) and rely on the user not using the definitions. That will allow the user to allocate an object of the corect size that it can pass to your library functions. So the complete type definition export allows the allocation by the user.
    – Paul Ogilvie
    2 mins ago





    @PetarVelev, another solution is to just export the type definitions (so no abstraction hiding) and rely on the user not using the definitions. That will allow the user to allocate an object of the corect size that it can pass to your library functions. So the complete type definition export allows the allocation by the user.
    – Paul Ogilvie
    2 mins ago













    up vote
    3
    down vote













    Typically you use void* to hide your implementation, e.g.



    void *create_foo(int param1, int param2);
    void print_foo(void* foo);
    int operate_on_foo(void* foo);


    So you "cast" the void* in your functions to your internal type.



    The downside of this is, that the compiler can't help you with the types, e.g. the user of the library can use a int* and pass it to your function and the compiler will accept it. When you use an actual type, the compiler will complain.






    share|improve this answer
























      up vote
      3
      down vote













      Typically you use void* to hide your implementation, e.g.



      void *create_foo(int param1, int param2);
      void print_foo(void* foo);
      int operate_on_foo(void* foo);


      So you "cast" the void* in your functions to your internal type.



      The downside of this is, that the compiler can't help you with the types, e.g. the user of the library can use a int* and pass it to your function and the compiler will accept it. When you use an actual type, the compiler will complain.






      share|improve this answer






















        up vote
        3
        down vote










        up vote
        3
        down vote









        Typically you use void* to hide your implementation, e.g.



        void *create_foo(int param1, int param2);
        void print_foo(void* foo);
        int operate_on_foo(void* foo);


        So you "cast" the void* in your functions to your internal type.



        The downside of this is, that the compiler can't help you with the types, e.g. the user of the library can use a int* and pass it to your function and the compiler will accept it. When you use an actual type, the compiler will complain.






        share|improve this answer












        Typically you use void* to hide your implementation, e.g.



        void *create_foo(int param1, int param2);
        void print_foo(void* foo);
        int operate_on_foo(void* foo);


        So you "cast" the void* in your functions to your internal type.



        The downside of this is, that the compiler can't help you with the types, e.g. the user of the library can use a int* and pass it to your function and the compiler will accept it. When you use an actual type, the compiler will complain.







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered 1 hour ago









        hellow

        2,87411836




        2,87411836




















            up vote
            2
            down vote













            You can do in foo.h:



            typedef struct internals_type;
            typedef struct
            uint16 a;
            internals_type* internals;
            public_type


            Including foo.h is then enough for your user to compile, without knowing what is exactly inside internals_type.






            share|improve this answer






















            • Yes, you're right!
              – Ludo
              1 hour ago














            up vote
            2
            down vote













            You can do in foo.h:



            typedef struct internals_type;
            typedef struct
            uint16 a;
            internals_type* internals;
            public_type


            Including foo.h is then enough for your user to compile, without knowing what is exactly inside internals_type.






            share|improve this answer






















            • Yes, you're right!
              – Ludo
              1 hour ago












            up vote
            2
            down vote










            up vote
            2
            down vote









            You can do in foo.h:



            typedef struct internals_type;
            typedef struct
            uint16 a;
            internals_type* internals;
            public_type


            Including foo.h is then enough for your user to compile, without knowing what is exactly inside internals_type.






            share|improve this answer














            You can do in foo.h:



            typedef struct internals_type;
            typedef struct
            uint16 a;
            internals_type* internals;
            public_type


            Including foo.h is then enough for your user to compile, without knowing what is exactly inside internals_type.







            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited 1 hour ago

























            answered 1 hour ago









            Ludo

            668314




            668314











            • Yes, you're right!
              – Ludo
              1 hour ago
















            • Yes, you're right!
              – Ludo
              1 hour ago















            Yes, you're right!
            – Ludo
            1 hour ago




            Yes, you're right!
            – Ludo
            1 hour ago

















             

            draft saved


            draft discarded















































             


            draft saved


            draft discarded














            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f52835726%2fhiding-internal-type-in-c-without-memmory-alocation%23new-answer', 'question_page');

            );

            Post as a guest













































































            Comments

            Popular posts from this blog

            List of Gilmore Girls characters

            What does second last employer means? [closed]

            One-line joke