class member pre-sizing

Hello,

I have a question about hiding class member definition of a definition 8-), I have a core_lib which links against private deps headers et cetera.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

#if core_lib_build
   #include "class_dep_type.defs"
#endif

namespace core_lib 
{
   class type_impl
   {

#if core_lib_build    
   class_dep_type m_wrapped;
#endif
   };
}


building core_lib -Dcore_lib_build=1 and delivering it

core_lib.h
libcore_lib.so

now someone will be using core_lib for building a public front-end:

1
2
3
4
5
6
7
8
9
10
11

#include "core_lib.h"

namespace my_lib 
{
   class my_type
   {
   
   core_lib::type_impl m_pimp;
   };
}


building my_lib -llibcore_lib

then question do I seek troubles doing so ?

meaning:

sizeof my_type = sizeof my_type + core_lib::type_impl, but as I am hiding m_wrapped refs core_lib::type_impl size is incomplete ; trying to avoid pointers and dynamic alloc ; do I have to put a dummy stuff like char add_dummy_size[128] in an else target?


Last edited on
Use an opaque (unique) pointer to insulate the implementation details.
See: http://herbsutter.com/gotw/_100/
hello,

I would prefer not using opaque or forward decl and ptrs, as those types are used a lot and collection-able; it would be a lot of dyn alloc / realloc at runtime especially on copy, then fragmentation ; it would degrade performances ; it can run on an embedded env,

so then my question as core_lib::type_impl is already compiled ; is the linker would be able to solve the real-size of it?


Last edited on
Something along these lines, perhaps:

1
2
3
4
5
6
7
8
9
10
//////////////  core_lib.h  /////////////////

namespace core_lib
{
    class type_impl
    {
        double v[4] {0} ;
        // ...
    };
}


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//////////////  my_lib.h  /////////////////

namespace my_lib
{
    struct my_type
    {
        // all functions are non-inline
        // user-defined non-inline foundation operations
        //    constructors, copy/move constructors, copy/move assignment, destructor
        my_type( /* ... */ ) ;
        // ...

        private:
            enum { CORE_LIB_TYPE_IMPL_ALIGN = 8, CORE_LIB_TYPE_IMPL_SIZE = 32 };
            alignas(CORE_LIB_TYPE_IMPL_ALIGN) char opaque_impl[CORE_LIB_TYPE_IMPL_SIZE] ;
    };
}


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//////////////  my_lib.cpp  /////////////////

//#include "my_lib.h"
//#include "core_lib.h"

namespace my_lib
{
    my_type::my_type( /* ... */ ) /* ... */
    {
        static_assert( CORE_LIB_TYPE_IMPL_ALIGN == alignof(core_lib::type_impl), "wrong alignment" ) ;
        static_assert( CORE_LIB_TYPE_IMPL_SIZE == sizeof(core_lib::type_impl), "wrong size" ) ;
        ::new (opaque_impl) core_lib::type_impl( /* ... */ ) ; // construct with placement new
        // ...
    }

    // ...
}
Hello,

yes thx, I could verify this way ; but still this is not a topic where there are clear answers and might be totally random according to the platform and the compiler ; construct by placement would require calling the dtor before dealloc ; I feel dirty 8-)

another option, would be to write a script that inlines all the deps headers into a single one, core_lib_deps.h but still need to do some parsing to remove all the local #include directives ; this is still an issue in cpp not being able to deliver stripped public headers ; a compiler/header/tool would be welcome ; it could emit a tag with a predefined keyword on the stripped header.
Last edited on
Topic archived. No new replies allowed.