On Wed, Apr 29, 2026 at 6:25 AM Ankush <[email protected]> wrote:
> Reading through the Plan 9 source code, I've noticed enumerations are always 
> used without a tag. This aspect of the Plan 9 C style isn't covered by 
> style(6).
>
> Out of curiosity, I'm wondering if anyone knows the reason for the omission 
> of a tag from all enumerations, and why some source files use a mixture of 
> enum and #define when the auto-incrementing property of enums isn't being 
> used.

I suspect mostly because the tags aren't actually that useful, and
Plan 9 style favors omitting ceremony where it can.  An `enum` in C is
not strongly typed; for all intents and purposes it is an `int`.

> In most C code bases, an enum is useful (instead of a macro) because it is 
> named and the compiler can produce warnings accordingly (e.g. missing enum 
> case in a switch statement) , or because the values in the enumeration should 
> be sequential and the compiler can take care of that instead of requiring the 
> programmer to manually assign values.

It is important to understand that "Plan 9 C" is not "C" as far as the
ISO standard goes. It's not too far off, but enough so that it is a
distinct dialect. Thus, many of the things that one may be used to
from standard C may be subtly different in Plan 9 C. In this case, the
Plan 9 C compilers do not emit warnings for missing case statements
over an `enum` in a switch.

> I've picked some examples to make the question more clear, this usage of enum 
> can be seen all throughout the Plan 9 source:
>
> From /sys/src/cmd/cc/cc.h
>
> enum    // no tag, e.g. could be enum OS; why not just use #define for these?
> {
>         Plan9 = 1<<0,
>         Unix = 1<<1,
>         Windows = 1<<2,
> };
>
>
> From /sys/src/9/boot/boot.h
>
> enum    // Why not #define? The enum isn't named and the values are manually 
> assigned
> {
> Statsz= 256,
> Nbarg= 16,
> };
>
> Hopefully someone out there has more insight on this!

Well, consider what `#define` does and when: strictly speaking, it
does textual substitution in the preprocessor, before code makes it to
the compiler's frontend; macros defined with `#define` do not need to
be semantically meaningful, or even syntactically valid: they are just
text.

This bears on the question at hand in that if one considers `enum`
variants, they actually _are_ semantically meaningful and must follow
the syntax rules of the language. Moreover, they define symbols that
could be emitted into object code (I don't recall whether or not they
actually are on Plan 9; an experiment just now suggests they are not),
and thus inspected with a debugger, and so on.

This is also specifically mentioned in, "The Practice of Programming",
by Kernighan and Pike; an excellent book for those who have not
already read it.  Specifically, on page 20 they write:

|_Define numbers as constants, not macros_.  C programmers
|have tarditionally used `#define` to manage magic number
|values.  The C preprocessor is a powerful but blunt tool, however,
|and macros are a dangerous way to program because they change
|the lexical structure of the program underfoot.  Let the language
|proper do the work.  In C and C++, integer constants can be defined
|with an `enum` statement....

Of course, `enum` is not a panacea.  It's only recently in standard C
that `enum` has grown the ability to define unsigned values, for
instance.

Does that clear things up a bit?

        - Dan C.

------------------------------------------
9fans: 9fans
Permalink: 
https://9fans.topicbox.com/groups/9fans/T17a31ae1d8c1feb4-Me7f2ab054a5d7b054e00a9a2
Delivery options: https://9fans.topicbox.com/groups/9fans/subscription

Reply via email to