Switch embedded in enum definition?

Programming, for all ages and all languages.
Post Reply
User avatar
Schol-R-LEA
Member
Member
Posts: 1925
Joined: Fri Oct 27, 2006 9:42 am
Location: Athens, GA, USA

Switch embedded in enum definition?

Post by Schol-R-LEA »

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: Select all

    // 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.
Rev. First Speaker Schol-R-LEA;2 LCF ELF JAM POEE KoR KCO PPWMTF
Ordo OS Project
Lisp programmers tend to seem very odd to outsiders, just like anyone else who has had a religious experience they can't quite explain to others.
sj95126
Member
Member
Posts: 151
Joined: Tue Aug 11, 2020 12:14 pm

Re: Switch embedded in enum definition?

Post by sj95126 »

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!"
User avatar
xenos
Member
Member
Posts: 1118
Joined: Thu Aug 11, 2005 11:00 pm
Libera.chat IRC: xenos1984
Location: Tartu, Estonia
Contact:

Re: Switch embedded in enum definition?

Post by xenos »

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

Code: Select all

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)
};
Programmers' Hardware Database // GitHub user: xenos1984; OS project: NOS
moonchild
Member
Member
Posts: 73
Joined: Wed Apr 01, 2020 4:59 pm
Libera.chat IRC: moon-child

Re: Switch embedded in enum definition?

Post by moonchild »

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

Code: Select all

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

enum {
        BASEADDR = RASPI_BASEADDR(RASPI_VER),
};
User avatar
Kazinsal
Member
Member
Posts: 559
Joined: Wed Jul 13, 2011 7:38 pm
Libera.chat IRC: Kazinsal
Location: Vancouver
Contact:

Re: Switch embedded in enum definition?

Post by Kazinsal »

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.
Post Reply