lundi 1 mars 2021

Returning an initialized structure from local scope unexpectedly works in C11

In our code base, I encountered some C code that I am not able to understand why it works.

Pretty sure implements some pattern found on the internet. Ideally this code should emulate some object-oriented pattern from C++, and it is used to create queues.

Here is (part of) the code for the declaration (.h) of the queue module:

struct Queue_t
{
  uint8_t         Queue[MAX_QUEUE_SIZE];
  uint32_t        Head;
  uint32_t        Tail;
  uint16_t        Counter;
  Queue_return_t  (*Push)(struct Queue_t * Queue, uint8_t * NewElement, uint16_t ElementSize);
  Queue_return_t  (*Pop)(struct Queue_t * Queue, Queue_Element_t *RetElement);
  Queue_return_t  (*Flush)(struct Queue_t * Queue);
};

extern const struct QueueClass {
        struct Queue_t (*new)( void );
} Queue_t;

struct Queue_t new( void );

Here is (part of) the code for the implementation (.c) of the queue module:

struct Queue_t new( void )
{
  struct Queue_t NewQueue;

[...]
  NewQueue.Push = &QueueManager_Push;
  NewQueue.Pop = &QueueManager_Pop;
  NewQueue.Flush = &QueueManager_Flush;
  return NewQueue;
}

const struct QueueClass Queue_t={.new=&new};

then the usage in the code is the following:

struct Queue_t Output_Queue;
Output_Queue = Queue_t.new();
[...]
RetQueue =  Output_Queue.Pop(&Output_Queue,Output_Queue_elem);

Now, we switched to a more straightforward queue implementation. Still I am not able to grasp what is going on in this code.

As stated in the title, my problem is in the "new" function, where a struct Queue_t is declared in a local scope and then returned.

As further information, in the project that used this "queue" module there was no dynamic memory allocation, hence no heap, free or malloc.

Everything worked really smooth, I would expect the code to crash as soon as the stack for the referenced object is freed and the pointer to the structure is accessed.

Also, the compiler used was IAR and is not complaining (this code was used on a uC).

Maybe the const qualifier is involved?

Any hint on what is going on?

Aucun commentaire:

Enregistrer un commentaire