Category: Programming
Tags: #c #cpp
Published: 2024-12-08

I was just thinking about this the other day and thought I would document it. Ok, ok, to be clear, I didn’t really even come close to inventing C++ but I was weirdly on track with a couple of the basic premises.

At the time, I was a very young man and had been writing primarily in C for almost 5 years at this point. I was writing a module for managing memory and became fascinated with trying to keep everything associated with the pointer together. I ended up with a strange and impractical implementation that I was kind of pleased with at the time. It looked something like this (vague approximation from memory):

The Buffer

struct Buffer
{
    void *memory;
    int size;
    void (*allocate)( struct Buffer *, int );
    void (*delete)( struct Buffer * );
    bool (*writeString)( struct Buffer *, const char * );
    void (*destroy)( struct Buffer * );
};

The buffer itself is a structure that contains:

The Pseudo-Constructor

struct Buffer *BufferCreate( int size )
{
    struct Buffer *buffer = malloc( sizeof( struct Buffer ) );
    if( !buffer )
    {
        return NULL;
    }

    buffer->memory = NULL;
    buffer->size = 0;
    buffer->allocate = BufferAllocate;
    buffer->delete = BufferDelete;
    buffer->writeString = BufferWriteString;
    buffer->destroy = BufferDestroy;

    buffer->allocate( buffer, size );
    
    return buffer;
}

The Pseudo-Destructor


void *BufferDestroy( struct Buffer *buffer )
{
    buffer->delete( buffer );
    free( buffer );
    
    return NULL;
}

The Pseudo-Methods


int BufferAllocate( struct Buffer *buffer, int size )
{
    if( buffer->memory )
    {
        buffer->delete( buffer );
    }

    buffer->memory = malloc( size );
    if( buffer->memory )
    {
        buffer->size = size;
        ( ( char * )buffer->memory )[ 0 ] = '\0';
    }
    else
    {
        buffer->size = 0;
    }

	return buffer->size;
}

void BufferDelete( struct Buffer *buffer )
{
    if( buffer->memory )
    {
        free( buffer->memory );
        buffer->memory = NULL;
        buffer->size = 0;
    }
}

bool BufferWriteString( struct Buffer *buffer, const char *string )
{
    if( !buffer->memory || !string )
    {
        return false;
    }

    strncpy( ( char * )buffer->memory, string, buffer->size );
    ( ( char * )buffer->memory )[ buffer->size - 1 ] = '\0';
    
    return true;
}

Putting it to Use

Again, this is just a vague approximation of something I wrote a very very long time ago before my brain was fully formed so, get off my case.

Based on the above implementation, this would be the basic usage of using the buffer structure thing:

int main() 
{
	// Create a buffer with an allocation of 20 bytes.
	
    struct Buffer *buffer = BufferCreate( 20 );
    if( !buffer ) 
    {
        fprintf( stderr, "Failed to create buffer\n" );
        return 1;
    }

	// Realocate the buffer as 255 bytes.
	
    buffer->allocate( buffer, 255 );

	// Write a string to the buffer.

    if( buffer->writeString( buffer, "This is a test") ) 
    {
        printf( "Buffer content: %s\n", (char *)buffer->memory );
    } 
    else 
    {
        printf( "Failed to write string to buffer\n" );
    }

	// Destroy the buffer.

    buffer = buffer->destroy( buffer );
    
    return 0;
}

Final Thoughts

As you can see, the approach itself is highly impractical and doesn’t make much sense but I was following my muse so, again, get off my case. Probably 6 months later, Turbo C++ 1.0 was released and I was introduced to classes and objects, at which point, it became very clear as to what my brain was getting at with this weirdness. I was trying to model objects in a weird C way. I had grouped functions into function pointers and had a basic implementation of the ‘this’ pointer. This probably explains why I took to C++ as quickly as I did. Turns out I was already on that path and that my tiny brain was actually trying to formulate the kernel of a very different paradigm.