I observed a compilation error from clang-800.0.38 on a MacBook when using a c enum and a Cython cpdef enum. I could reproduce the issue using gcc version 4.9.2 (Raspbian 4.9.2-10). In both cases, Cython version 0.25.1 was used.
The code I ran was:
#lib.h
typedef enum { A, B, C, D} foo;
#lib.pyx
cdef extern from "./lib.h":
cpdef enum foo:
A, B, C, D
def t1():
for e in foo: print(e.name)
When trying to compile, clang throws a lot of errors which all seem to correlate with the "enum foo".
A solution is to declare the enum in the .h file as following typedef enum foo { A, B, C, D} foo;or as typedef enum foo { A, B, C, D};. When changed, the code is compiled and linked to a .so file and is working as intended.
Is this intended behaviour or bug?
@adippel I observed the same issue with Cython 0.25.2. Using the foo example above, the errors that were generated looked as follows:
lib.hpp:XXX: note: foo has a previous declaration here
when I changed the typedef enum {A, B, C, D} foo; to typedef enum foo {A, B, C, D} foo; the error went away. Is this intended behavior?
@robertwb is this a simple fix considering the work done on issue #531 ?
That is because cpdef enum is a variant of cdef enum which declares a non-typedef'd enum. If you declare a typedef'ed enum as a "plain" enum or vice versa it'll generate the wrong code. There's no typedef variant of cpdef enums (would that be cptypedef)?
http://cython.readthedocs.io/en/latest/src/userguide/external_C_code.html#styles-of-struct-union-and-enum-declaration
Is cptypedef something that we can add?
My current workaround is rather verbose, especially when there are a lot of enums values. It looks something like this:
cdef extern from './lib.h':
ctypedef enum _foo 'foo':
_A 'A'
_B 'B'
_C 'C'
_D 'D'
cpdef enum foo:
A = _A
B = _B
C = _C
D = _D
My actual code is even more verbose because I prefix the ctypedef enum names so they don't pollute the global namespace.
+1 for some kind of "cptypedef". Kinda ugly but I don't see a better way...
Most helpful comment
+1 for some kind of "cptypedef". Kinda ugly but I don't see a better way...