This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

ARM Tiva enum size issue



We have a CCS solution with many projects. Several are TMSC1294 and use TI compiler v5.2.2 and several are MINGW builds for a parallel PC based build.

I ran into the issue with the code generated by the ARM compiler for enum values. It seems the MINGW build follow the C99 standard where enums are by default ints which leads to a sizeof() = 4; With the exact same code compiled for the Tiva I get sizeof() = 1. This causes issues which I will not go into detail here. It seems, by default, the TI compiler optimizes enums when the number of elements are less than 256. I found a way to over ride this by setting Build->ARM Compiler->Advanced Option->Run Time Model Option->Designate enum type from its default of “packed” to “Int”. Unfortunately because of all the projects and permutations of these projects it is not practical for me to go in and change this setting in every single project. And besides how can I be assured anyone creating a new Tiva project will remember to go in and change this obscure compiler setting. I asked before if it might be possible to somehow set this globally and I was told it is not possible (please correct me if this is wrong). Another option I was thinking about is if it might be possible to set this in an .h file? I know some compilers allow compile options in the actual header file. Is this possible? If so, what might the syntax be to set this?

  • Consider using the environment variable TI_ARM_C_OPTION.  The compiler adds the options in that variable to every build.  It is documented in the ARM compiler manual.  In your case, something like this would work ...

    C:\working\directory> set TI_ARM_C_OPTION=--enum_type=int

    Thanks and regards,

    -George

  • I saw that too. unfortunately I tried that and it does not seem to work ...at least from the IDE build. The console window (and log file) does NOT show the option being set. It might work for a command line build but I did not try it.

    I would also have to inform all our developers (and we have quite a few) to all set this environment option as well on our official automated build machine and make sure any newly installed machine also gets set as part of the install procedure (yuck!).

    Having this in a file or included in a .h file would be ideal but not sure this is possible???

  • DavidVescovi said:
    I tried that and it does not seem to work ...at least from the IDE build.

    Sorry.  I should have thought of that.  The command I show above affects only the environment of that command line window.  To affect the environment of the entire Windows OS takes a bit more.  Here is how it looks on my Windows 7 laptop : Start | Control Panel | System | Advanced system settings | Environment Variables.  Expect it to be a bit different on other versions of Windows. After making the change, restart CCS.

    I agree this solution is not ideal.

    Another less than ideal suggestion ... You can force an enumerated type to be a certain size by adding an unused member that is set to the size of a large enough value.  For example ...

    #include <limits.h>  /* for INT_MAX */
    enum colors { red, green, blue, never_used=INT_MAX };

    The disadvantage is you have to do this for every enumerated type where the size matters.  Perhaps you don't have too many such types.

    Thanks and regards,

    -George

  • Another messy option to consider:

    Go ahead and depend on the proper compiler settings (which I believe is lack of --small_enum).

    As a way to mitigate worry about this accidentally getting set wrong in future, you could add a static assert verifying that the size of a special enum is 4 bytes  This special enum would just be one that would be sized 1 byte with --small_enum and 4 bytes without --small_enum.

    In whatever header file you were considering adding the "compile options in the actual header file", you could try something like:

    #pragma once

    #define static_assert(argExpr) ((void)sizeof(char[(argExpr) ? 1 : -1]))

    enum TestEnum
    {
        TEST_ENTRY = 0
    };

    static void testEnumFunc()
    {

      // If this generates a compiler error, please remove the --small_enum compiler option
        static_assert(sizeof(TestEnum) == 4);
    }

    Now when someone builds a source file that includes this header file, they will get a build error if the --small_enum option is set for that file.

    (I haven't actually tried this, so this may not work.)

    ---

    Update: --enum_type seems to be the compiler option the OP is having problems with.  When reading the above, one can consider --enum_type alongside --small_enum.

  • Don't know what --small_enum has to do with it. These are not set nor or they set by default. It does not pertain to this issue.

    You are correct both yours or the previous proposed solution are far from ideal. The first proposal I can not use because I do not control the header files of concern.

    Your solution does come closer.

    Here is another proposal ... change the compiler default to follow the C standard and follow the documentation of the compiler as stated on page 32 which clearly states:

    --enum_type={int|packed| Designates the underlying type of an enumeration type. The default is

    unpacked} unpacked, which designates the underlying type as int if the

    enumerator constants can be represented in int. In C++, the

    underlying type is long long if an enumerator constant cannot be

    represented by int or unsigned int.

    Using --enum_type=packed forces the enumeration type to be

    packed, which designates the underlying type of the enumeration is

    chosen to be the smallest integer that accommodates the enumerator

    constants.

    Using --enum_type=int designates the underlying type to always int.

    An enumerator with a value outside int range generates an error.

    This statement is in error as the default is packed ...which is the root of my issue. It seems packed some how means the "smallest integer that accommodates the enumerator" is a byte if I do a sizeof(one_of_my_enums) I get 1. If I set --enum_type=int I get the sizeof(one_of_my_enums) equal to 4. This is what I want.

  • Unfortunately, the documentation and the compiler do not agree.  In the compiler, the default is --enum_type=packed.  I filed an issue to have this addressed.  I'm pretty sure the fix will be to change the manual.

    Thanks and regards,

    -George

  • George Mock said:
    I filed an issue to have this addressed.

    The ID for the issue is CODEGEN-1287.  Feel free to follow it with the SDOWP link below in my signature.

    Thanks and regards,

    -George