OSDev.org
https://forum.osdev.org/

Switch embedded in enum definition?
https://forum.osdev.org/viewtopic.php?f=13&t=37471
Page 1 of 1

Author:  Schol-R-LEA [ Sat Nov 14, 2020 12:42 pm ]
Post subject:  Switch embedded in enum definition?

I was experimenting with the Raspberry Pi bare bones code, to see what I could learn from it, and ran across an odd bit of code in the C source. In the definition of the enum containing the MMIO, GPIO, and UART constants, the first entry, meant to define the MMIO base address, is:

Code:
    // The MMIO area base address.
    switch (raspi) {
        case 2:
        case 3:  MMIO_BASE = 0x3F000000; break; // for raspi2 & 3
        case 4:  MMIO_BASE = 0xFE000000; break; // for raspi4
        default: MMIO_BASE = 0x20000000; break; // for raspi1, raspi zero etc.
    }


Now, I will admit that I tried to compile this blind, as part of what I wanted to see was how easy the tutorial was to follow. Not surprisingly, GCC did not recognize this idiom as a legitimate way to define an enum constant. While the intent seems clear, it isn't legal C code, as far as I can tell.

I simply replaced it with the appropriate sub-entry (the case 3 entry), but the code as given caught my interest.

However, I am curious as to why this was in the code sample. Is there an actual way to do this using a switch() statement (as opposed to, say, #define and #ifdef directives)?

Is this in the code primarily as a 'copy trap' (by which I mean, it is there to force the programmers following the tutorial to actually read the code), or is there a real idiom which this is meant to apply?

As an aside, AFAICT the triplet for AArch64 has changed to 'aarch64-none-elf-' rather than just 'aarch64-elf-', presumably to improve the consistency with other triplets. I don't want to change this in the wiki page until I have confirmed this, however.

Author:  sj95126 [ Sat Nov 14, 2020 1:32 pm ]
Post subject:  Re: Switch embedded in enum definition?

It sure doesn't seem like that's legal. An enum can be a constant expression, which itself can be a conditional expression, but switch is neither of those.

You *could* do the same thing with a nested series of ternary operators, which are conditional expressions, but that would get pretty messy.

I know this makes me a grouch, but it's kind of annoying when coders use a feature to the extreme just because they can. I'm rarely impressed by "look how clever I am!"

Author:  xenos [ Sat Nov 14, 2020 1:43 pm ]
Post subject:  Re: Switch embedded in enum definition?

I'm not that familiar with C. In C++, I would probably use something similar by putting the switch in a constexpr function:

Code:
int constexpr rpi = 4;

unsigned int constexpr baseaddr(int raspi)
{
   switch (raspi)
   {
   case 2:
   case 3: return 0x3F000000; // for raspi2 & 3
   case 4: return 0xFE000000; // for raspi4
   default: return 0x20000000; // for raspi1, raspi zero etc.
   }
}

enum mmio : unsigned int
{
   MMIO_BASE = baseaddr(rpi)
};

Author:  moonchild [ Sun Nov 15, 2020 5:25 pm ]
Post subject:  Re: Switch embedded in enum definition?

I would use a macro with a ternary if. Something like this:

Code:
#define RASPI_BASEADDR(ver) (((ver == 2) || (ver == 3)) ? 0x3F000000 : \       
                             (ver == 4)                 ? 0xFE000000 : \
                             0x20000000)
#define RASPI_VER 3

enum {
        BASEADDR = RASPI_BASEADDR(RASPI_VER),
};

Author:  Kazinsal [ Mon Nov 16, 2020 1:50 am ]
Post subject:  Re: Switch embedded in enum definition?

That has to be a copy trap. It's such a blindingly absurd way of doing compile-time constants with a conditional base address that I can't imagine it being anything else.

Page 1 of 1 All times are UTC - 6 hours
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
http://www.phpbb.com/