-
-
Notifications
You must be signed in to change notification settings - Fork 2.8k
Problem with enums and translate-c #5242
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
This is intentional. If you want the integer value you can use |
I'm sorry, but you are missing the point. The zig function prototype that translate-c creates for the discussed function specifies the flag argument type as a (zig) enum. But the C function that it represents wants an ordinal value for the flag. But if you try to pass an ordinal value, the compiler complains, because an integer is not the same as an enum in Zig as it is in C. The issue is that the Zig function prototype produced by translate-c is incorrect, because it is not accounting for the different semantics of Zig vs C enums. |
This has been discussed previously in #2115. The ultimate resolution was explained here. I disagree with Andrew's assessment of C's type system, and you probably will also, but this is the reasoning for the current behavior. In terms of correctness, the generated enum is extensible, so all flag combinations are valid values for the enum. They just don't have names. So the generated function signature is correct, it's just a bit annoying to work with because you have to use Zig doesn't currently have a nice way to represent flag types that is guaranteed to be ABI-compatible with a C enum, except using an untyped integer. #5049 is a proposal targeted at fixing that problem. Once an ABI-compatible flag type is in the language, we could consider trying to identify enums that are used as flags in translate-c and translate them as flags. |
" So the generated function signature is correct, it's just a bit annoying to work with because you have to use @intToEnum at the call site." That suggests to me that if I convert an integer flag, e.g., GTK_DIALOG_MODAL. back to an enum, as you say, that what will actually get passed to the C function is its ordinal value? And so despite the to-ing and fro-ing, the right thing happens? And if you look at the translated definition of GtkDialogFlags in my original post, the @intToEnum call might not even be necessary, since GtkDialogFlags.GTK_DIALOG_MODAL is available, which carries the enum type. If my speculation in this paragraph is correct, then perhaps this is not the problem I thought it was. I will leave it open until I've read issue #2115, which you cited. |
Yeah, extern enums are guaranteed to be ABI-compatible with C enums. The |
Ok, good. Thanks much for the explanation. I am not quite at the point of testing the code in question, but certainly proceeding using the path you set me on is getting me past the compilation problems. I just have to sort out some other stuff before I test. I expect this will all just work. If nothing else crops up relevant to this, I will close the issue. |
I did test the code written as discussed in previous messages and it works fine on a Slackware Linux system. I also happen to have a FreeBSD system at the moment and tested it there and it seg-faulted. Some digging with gdb suggests to me that the problem has nothing to do with the issue at hand, so I'm going to close this one. I also note that there is discussion of this issue in the Zig documentation, however terse, that extern enums are C ABI compatible and the C translator did translate the gtk enum we're discussing as extern. So part of my concern here was due to my own failure to read the documentation as carefully as I should have. |
Working on an application that uses gtk3, I am using translate-c to turn gtk.h into gtk.zig (I'm essentially doing the @cimport in a separate makefile step, to avoid doing the transaction on every recompilation; gtk.h plus all its includes is huge).
I want to call
which gets translated as
The difficulty is the flags argument. GtkDialogFlags is an enum in C. It gets translated as
The problem is that in C, enums are their integer values, whereas in zig a distinction is made between the enum type and its ordinal values. So if I try to call gtk_dialog_new_with_buttons with a flags argument of, say, GTK_DIALOG_MODAL, as translated by translate-c, I get an error from the compiler, complaining that it is expecting the enum type and I handed it a c_int:
But the C function I'm calling wants the ordinal value that I am supplying. The problem is that translate-c has defined the flag parameter of that function as a Zig enum, and
what the C function wants is an ordinal value.
I have a C interface file in this application that I am using to get around situations like this where translate-c does not work perfectly or at all, e.g., when C pre-preprocessor macros are needed. I can work around this problem by creating an interface function that expects an integer for the flags argument.
The text was updated successfully, but these errors were encountered: