Search code examples
c++linkerpimpl-idiom

Finding a way to use PIMPL with external constant definitions for the size of an array inside the implementation


We have the following situation: We are using a processor which has defined sections inside its RAM, which must be used by a special implementation using the PIMPL-Principle. For example the private Implementation would look like this:

Impl( )
{
public:
  void doSomething()
  {
    for( uint32_t i = 0; i < DATA_SIZE; ++i )
    {
      // do stuff with buf[i]
    }
  }
private:
  
  static uint8_t  buf[DATA_SIZE] __attribute__ ((section("data_buffer"), aligned (8)));
};

As you see DATA_SIZE is not defined here. The point here is that we can use the processor-vendor-provided functions inside the Impl on different processors of the same vendor with different Linkerscripts defining the section "data_buffer". This is possible because the used underlying system provides the same functions for different processors of the same family. But it must be a PIMPL to guarantee that if I change to a different processor of another vendor, we can use another Impl for the other vendor. So it can happen someone is using the section with a different DATA_SIZE because he defines his sections in a different manner in his project (even on the same processor). The initialization and everything will be of course done via the constructor etc.

But is it possible to make the DATA_SIZE settable and not to define it directly in the Impl-File?

As I know of the PIMPL the target is to compile it and to have a defined ABI, which for me means that the compiled file can't change in size afterwards when linking. Is my thought right? (for me it is for now only to quickly change the implementation and never touch the upper laying PIMPL-using software-part, but we will use a "pimpl-library" in the future, where we want to just change the compiled Impl-files.)

I wanted to prevent the usage of a Base-/Interface-Class from which you derive to fully hide the implementation to the developer and not passing any references or pointers of the derived class because this will need a software change in the upper layers.

Thank you for your thoughts.


Solution

  • But is it possible to make the DATA_SIZE settable and not to define it directly in the Impl-File?

    The size of a non-static member array must be set in the class definition.

    You can include the value from elsewhere using the pre-processor, so it doesn't have to be "in the file" in that sense, but what ever that size is, it must match across all TU and changing the size only inside the private implementation without modifying the clients of the interface is not possible..


    Note that as long as you define the array to be at least the size and alignment of a pointer, then you can have any data in the private implementation using indirection - by storing a pointer and creating the concrete object in dynamic storage.