0

I apologize if my terminology is not perfect, I am a self taught programmer :) My automatic machine has different moving parts, and for each one I have a C file handling its own state machine. Each C file has an enum defining all the states for that state machine, for example:

movingArm.c

enum { 
    STANDBY = 0,
    ARM_OPEN,
    ARM_CLOSE,
    ARM_WAIT  
};


void state_machine_arm()
{
    switch(status_arm)
    {
        case STANDBY:
            // ....
        break;

        /* etc */
    }
} 

everything is running smoothly but sometimes I have to check the state of one state machine from another file, and so it would be handy to have all the enums in one common place to be accessed by all the files. Instead of every time checking what number corresponds to which states and having a huge risk of missing something.

So the question is: what's the best practice in this case? can all the enums be grouped in a single header file and included in all the .c files?

edit: I add some details, maybe I wasn't clear enough. If from another file anotherPart.c I want to check the status of the arm:

if( get_status_arm() == ARM_OPEN )
{
    // do something
}

I need to know what ARM_OPEN corresponds to, so ARM_OPEN should be defined also in anotherPart.c

This is why I thought about a common header file, to avoid re-declaring the enum in anotherPart.c (it would be even more annoying if I have to add or change something in the enum)

Val
  • 280
  • 3
  • 13
  • Consider generating some C code (perhaps some `#include`-d file) with some other software. Take inspiration from http://swig.org/ and perhaps use [GNU bison](https://www.gnu.org/software/bison/) in your own C code generator – Basile Starynkevitch Mar 03 '21 at 09:53
  • 7
    You've basically answered your one question. Simply put the `enum` in some header file and include it whereever you need it – Jabberwocky Mar 03 '21 at 09:56
  • Please clarfiy whether what you need to share among .c files is the declaration of the enum type (in that case @Jabberwocky comment would be the answer) or whether you are referring to variables which need to be defined one and declared for use in many .c files. You can clarify that by showing a [mre] of two or three files which demonstrate what you are describing. You might also need to clarify whether you are doing multithreading/tasking. – Yunnosch Mar 03 '21 at 09:59
  • I edited the question with more details. @Jabberwocky is that correct to have multiple enums in a single header file or is that bad practice? – Val Mar 03 '21 at 10:14
  • 1
    @Val no it's not bad practice, it's even a very current practice. – Jabberwocky Mar 03 '21 at 10:17
  • ah ok :) very good to know, thank you @Jabberwocky!! – Val Mar 03 '21 at 10:18
  • 1
    `is that correct to have multiple enums in a single header file` Not the best example but [two enums in the same .h file](https://github.com/lattera/glibc/blob/895ef79e04a953cac1493863bcae29ad85657ee1/sunrpc/rpc_parse.h#L34). State machine is something everyone has written, research the web how to write it in C, there will be endless examples. One of my first google hits [this pdf](https://www.adamtornhill.com/Patterns%20in%20C%202,%20STATE.pdf) looks like a nice read. Also https://stackoverflow.com/questions/133214/is-there-a-typical-state-machine-implementation-pattern . – KamilCuk Mar 03 '21 at 10:30

1 Answers1

2

So the question is: what's the best practice in this case? can all the enums be grouped in a single header file and included in all the .c files?

Yes, that would be the best practice. typedef enum { ... } arm_state_t; in a header file. Then in the same file provide a getter function which can return the internal state to those interested:

arm_state_t get_status_arm (void);

Also, as always, use include guards in the header. Creating your own header file in C

Lundin
  • 195,001
  • 40
  • 254
  • 396
  • thank you. Just one more thing: what if the different ENUMS have some elements with the same name (same name among different enums, not in the same one)? it looks like the compiler doesn't like it.. – Val Mar 03 '21 at 11:34
  • 1
    @Val Enumeration constants (`enum { /* this stuff here */ }`) live in the same namespace as most other identifiers. Not to be confused with struct/union members that have their own private namespace. This is typically solved by source code prefix, naming them `ARM_` etc as done in your case. – Lundin Mar 03 '21 at 11:39