OSDev.org

The Place to Start for Operating System Developers
It is currently Sat Mar 06, 2021 8:50 pm

All times are UTC - 6 hours




Post new topic Reply to topic  [ 5 posts ] 
Author Message
 Post subject: Switch embedded in enum definition?
PostPosted: Sat Nov 14, 2020 12:42 pm 
Online
Member
Member
User avatar

Joined: Fri Oct 27, 2006 9:42 am
Posts: 1738
Location: Athens, GA, USA
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.

_________________
Rev. First Speaker Schol-R-LEA;2 LCF ELF JAM POEE KoR KCO PPWMTF
μή εἶναι βασιλικήν ἀτραπόν ἐπί γεωμετρίαν
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.


Top
 Profile  
 
 Post subject: Re: Switch embedded in enum definition?
PostPosted: Sat Nov 14, 2020 1:32 pm 
Offline
Member
Member

Joined: Tue Aug 11, 2020 12:14 pm
Posts: 96
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!"


Top
 Profile  
 
 Post subject: Re: Switch embedded in enum definition?
PostPosted: Sat Nov 14, 2020 1:43 pm 
Offline
Member
Member
User avatar

Joined: Thu Aug 11, 2005 11:00 pm
Posts: 1106
Location: Tartu, Estonia
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)
};

_________________
Programmers' Hardware Database // GitHub user: xenos1984; OS project: NOS


Top
 Profile  
 
 Post subject: Re: Switch embedded in enum definition?
PostPosted: Sun Nov 15, 2020 5:25 pm 
Offline
Member
Member

Joined: Wed Apr 01, 2020 4:59 pm
Posts: 65
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),
};


Top
 Profile  
 
 Post subject: Re: Switch embedded in enum definition?
PostPosted: Mon Nov 16, 2020 1:50 am 
Offline
Member
Member
User avatar

Joined: Wed Jul 13, 2011 7:38 pm
Posts: 556
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.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 5 posts ] 

All times are UTC - 6 hours


Who is online

Users browsing this forum: No registered users and 2 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group