Enum values are siblings of their type, not children of it.

4,228 views
Skip to first unread message

alopecoid

unread,
Aug 20, 2010, 2:12:30 PM8/20/10
to Protocol Buffers
Hi,

This post is about the fact that protobuf enum values use C++ scoping
rules, meaning that, unlike in Java, enum values are siblings of their
type, not children of it.

Say I have the following contrived message:

message MyMessage {
enum Foo {
FIRST = 0;
SECOND = 1;
BOTH = 2;
}
required Foo foo = 1;

enum Bar {
FIRST = 0;
SECOND = 1;
BOTH = 2;
}
required Bar bar = 2;
}

This wouldn't compile because the protobuf compiler recognizes the
fact that for C++, the generated enum values for Foo and Bar would
conflict with each other.

However, for Java, this wouldn't be a problem. I would like to propose
that instead of "punishing" the generated Java code because of C++'s
strange enum behavior (by forcing developers to rename their enum
values even though they don't collide), that instead, the generated C+
+ enum declarations are wrapped in their own nested namespaces? For
example, something like:

namespace Foo {
enum Enum {
FIRST = 0;
SECOND = 1;
BOTH = 2;
}
}

namespace Bar {
enum Enum {
FIRST = 0;
SECOND = 1;
BOTH = 2;
}
}

At this point, the enum values would be accessed like Foo::FIRST,
Bar::FIRST, etc, which would eliminate the enum value collision
problem altogether, and at the same time make them appear to behave
more like Java's enum scoping rules (which arguably make more sense).

Thoughts?

Thank you.

Kenton Varda

unread,
Aug 24, 2010, 5:56:39 PM8/24/10
to alopecoid, Protocol Buffers
How would you make this change without updating millions of lines of existing C++ code that uses protobuf enums?


--
You received this message because you are subscribed to the Google Groups "Protocol Buffers" group.
To post to this group, send email to prot...@googlegroups.com.
To unsubscribe from this group, send email to protobuf+u...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/protobuf?hl=en.


alopecoid

unread,
Aug 25, 2010, 8:09:34 PM8/25/10
to Kenton Varda, Protocol Buffers
It could be made an option. Something like...

message MyMessage {
enum Foo {
option cpp_namespace = true;
FIRST = 0;
...
}
...
}

...and then could be made the default if there is ever a Proto3.

But, even if this is just ends up on some "if-there-ever-is-a-Proto3"
to-do list, that would be cool... just so it's not forgotten about.
It's one of those small things that make the API nicer. I've come
across this scenario several times (and so have other colleagues).

Giri Guntipalli

unread,
May 28, 2013, 11:12:46 PM5/28/13
to prot...@googlegroups.com
Hi enum values conflict for C++ is there any solution now solution suggested below is available in latest version any workarounds to handle this problem with 2.4.1 or latert versions.
 
Giri

greg.mal...@gmail.com

unread,
Nov 1, 2013, 3:45:03 PM11/1/13
to prot...@googlegroups.com
The solution is available in the latest version??? Please elaborate. I'm using 2.5.0 and I don't see it.

-Greg

WonHee Jung

unread,
Nov 17, 2014, 8:09:13 PM11/17/14
to prot...@googlegroups.com
I don't think it's added in 2.4.1+. I don't see any related changes in changelog.

Teddy Zhang

unread,
Nov 9, 2015, 2:15:35 PM11/9/15
to Protocol Buffers
Sorry to dig this old thread.
I now one of the solution right now is to put the enum to different proto file and put them into different package. But that doesn't really work if the enums are under the same message.

I would suggest add an option for c/c++, like below:
enum Foo {
      option c_enum_prefix = "eFoo";

      FIRST = 0;
      SECOND = 1;
      BOTH = 2;
    }

And it will generate enum like below in c/c++:
enum Foo {
    eFooFIRST = 0,
    eFooSECOND = 1,
    eFooBOTH = 2
};

This won't affect enum generation in managed language like java/c#, and it won't break backward compatibility (if the option is not specified, fallback to old behavior).

Any comments?

GoldenBull Chen

unread,
Dec 28, 2015, 1:34:10 PM12/28/15
to Protocol Buffers
Agree. It's a bad design to use old C++ scoping rules for enum values. Even C++ itself has introduced enum class in C++11.

在 2015年11月10日星期二 UTC+8上午3:15:35,Teddy Zhang写道:

GoldenBull Chen

unread,
Jan 2, 2016, 10:16:09 PM1/2/16
to Protocol Buffers

https://github.com/google/protobuf/issues/1079

在 2010年8月21日星期六 UTC+8上午2:12:30,alopecoid写道:
Reply all
Reply to author
Forward
0 new messages