0

in effective C++, I learn that item 2 says it's not legal to take the address of an enum anywhere in the program and it's typically not legal to take the address of a #define, either. but i write such code that it tries to take the address of an enum type:

#include<iostream>
using namespace std;
int main() {
enum week { mon=1, tue }day;
week* a = &day;
return 0;
}

it can run without mistakes. so i feel confused about this item.

ingridli
  • 5
  • 2
  • 2
    `day` is a local variable, not an enum. `week` is an enum. – Jeremy Friesner Oct 13 '22 at 03:25
  • 3
    They probably meant you can't take the address of one of the values of an enum, so `& mon` or `&tue` wouldn't compile. But `day` is basically a variable of some integer type, so taking its address is like taking the address of another integer variable. You can't take the address of the enum type either, but then, you can't take the address of any type (e.g., `& int` won't compile, and makes no real sense). – Jerry Coffin Oct 13 '22 at 03:26
  • 3
    You have to differ between enumeration *types* (like `week`), enumeration *constants* (lkike `mon`) and *variables* of an enumeration type. – Some programmer dude Oct 13 '22 at 03:30
  • 4
    While it turned out harmless in this case, do note that "it can run without mistakes" is a very poor indicator in C++ of undefined behavior, especially when poking around with aliasing and reference semantics. There is a *ton* of undefined behavior in C++ that will "just work" sometimes in some compilers on some computers and then fail at the wrong moment, or crash when an optimizer hits it. – Silvio Mayolo Oct 13 '22 at 03:35
  • *"Undefined behavior means anything can happen inlcuding but not limited to the program giving your expected output. But never rely on the output of a program that has UB. The program may just crash."* – Jason Oct 13 '22 at 03:42
  • 4
    If you read something that does not make sense to you, it is often wise to provide an exact quote of what you read. Paraphrasing what you read colors it with your own misunderstanding, which could make your question hopelessly confused. – JaMiT Oct 13 '22 at 05:21
  • Reopened. There is no undefined behavior here. – Pete Becker Oct 13 '22 at 13:00
  • Types don't have addresses. Variables/objects do. – Jesper Juhl Oct 13 '22 at 13:02

2 Answers2

2

Your example code introduces five identifiers, namely week, mon, tue, day, and a. Each of the first four could reasonably be called "an enum" in a paraphrase of a misunderstood quote. Without a quote, it is difficult to tell to which of these the book refers. However, it is possible to list which identifiers can and cannot have their address taken.

  • &week -- not legal to take the address of a type
  • &mon -- not legal to take the address of an enumerator
  • &tue -- not legal to take the address of an enumerator
  • &day -- legal to take the address of a variable

The upshot of the quote is probably that enumerators – the values of an enumeration type, e.g. mon, tue – are not variables, so their address cannot be taken. Syntactically, the valid uses of mon closely match the valid uses of the numeric literal 1. In particular, just like one cannot take the address of a numeric literal (no &1 allowed), one cannot take the address of an enumerator (no &mon allowed).

JaMiT
  • 14,422
  • 4
  • 15
  • 31
  • "*the enumerates*" The correct term for these, from the standard, is "enumerators". The "enumeration" is the type that gets defined, and the "enumerators" are the things that go inside the enumeration definition. – Nicol Bolas Nov 25 '22 at 16:40
  • @NicolBolas Thanks. Apparently I picked up the wrong terminology years ago and never noticed. It's even the wrong part of speech (verb instead of noun). Oops. – JaMiT Nov 25 '22 at 16:43
0

In that phrase - 'the address of an enum', an 'enum' means a symbol you defined as a constant. In your code, mon and tue are enums. Experiment yourself like this.

void *p = &mon;
relent95
  • 3,703
  • 1
  • 14
  • 17
  • *"a symbol you defined as a constant"* -- this might not be how you want to describe the situation. It is possible to take the address of some symbols defined as constants. For example, given the definition `constexpr int monday = 1;` it is legal to take the address of this constant, as in `&monday`. So while your conclusion is good, your supporting argument is weak. – JaMiT Nov 25 '22 at 16:37
  • @JaMiT, I just said the correct interpretation of English words, not the appropriateness of a syntax of C++. The original sentence in the book is "For example, it’s legal to take the address of a const, but it’s not legal to take the address of an enum, and it’s typically not legal to take the address of a #define, either.". – relent95 Nov 26 '22 at 00:34