GNOME Bugzilla – Bug 584400
extern virtual/abstract member in an interface produces wrong ccode.
Last modified: 2009-07-29 02:40:16 UTC
Please describe the problem: public interface Buildable : Object { public extern virtual void foo(); } produces void g_yaml_buildable_foo (GYAMLBuildable* self); static void g_yaml_buildable_real_foo (GYAMLBuildable* self); void g_yaml_buildable_foo (GYAMLBuildable* self) { .... } which is not intended. (1) the ccode produces a symbol not found error for buildable_real_foo. (2) buildable_foo should not be implemented in the ccode. The implementation should be external. (3) buildable_real_foo should not be static, it should also be an exteranal function. public interface Buildable : Object { public extern abstract void foo(); } suffers from a similiar problem. produces Steps to reproduce: Actual results: Expected results: Does this happen every time? Other information:
Created attachment 135693 [details] [review] remove static from _real functions for external virtual members very small fix.
Created attachment 135694 [details] [review] remove the function bodies for extern virtual members. another very small fix.
Created attachment 135695 [details] compilation result of the test case compilation result of the test case
Created attachment 135696 [details] test case test case
An issue with this approach is that we expose the compiler internal `real' infix. I'm considering to just report an error when using extern with virtual/abstract. You can still call an extern non-virtual method from a Vala virtual method, which should be equally useful.
Not really equally useful, unless I sacrify the simpleness of the program. The underlying problem is that I need to have a different accessor function that can't be written or rewritten in VALA. The function behaves like GtkBuildable.set_name, which takes a default action if the object doesn't implement the interface at all. In your suggested way I have to do this interface Buildable { public extern void set_name(); public virtual real_set_name() { } } // in c: void buildable_set_name(Buildable * pointer ) { blah blah blah if pointer is Buildable, call real_set_name if pointer is not a buildable do something else } Because we are forcing one purpose into two names, one of them has to be ugly. Now the infix real explictly spoils the vala source code! On the other hand what about also introduce a ccode attribute for the _real_ function name. I think it is completely sane and useful to allow this. With this new attribute _real is no longer an internal infix but merely a rule for the default value for a codegen attribute, just like `cname'.
Is the real issue for your use case that you need a fix for bug 546305?
Sorry but I don't get bug 546305. The report is laconic. Does it mean to make the accessor also virtual? I don't think it is sufficient for my case anyways. I'll still need to supply the accessor as external C code because I need to (1) selectively invoke the derived implementations in the base implementation of the accessor; this is reversed comparing with virtual function overiding (2) skip the type check on the instance.
Created attachment 135822 [details] [review] real cname as a ccode attribute
Created attachment 135823 [details] test for the real_cname(135822)
Created attachment 135826 [details] Test extern overriden methods.
In relation to one of the original examples, I'd like to point out that "abstract" can't be "extern", as "abstract" means there is no implementation.
You are right, abstract doesn't have implementation. it makes no sense to decorate the implementation function with extern for an abstract member. However there is the stub function to dispatch the virtual function call. I don't see a reason why this stub function cannot be extern. Unless you can convince me there is a better way to achieve with vala the same thing done as in gtk_widget_show: perform complicated check, setup the preconditions, then emits the signal that carries the virtual function. gdk_drawable_set_colormap: perform an extra simple check before dispatch the v-func invocation.
In my opinion, having anything in the vfunc wrapper other than just a call to the implementation is an abuse of the virtual function mechanism, I don't really want to encourage these strange wrapper functions. If you need methods that work if the instance implements a particular interface or not, use static methods and type checks. Falling back to something completely different doesn't sound right. We might be able to achieve something like what you want if we add extension methods or similar to Vala.
commit 4a6a5376c6316a2be5f587360f01095edcb6ee0e Author: Jürg Billeter <j@bitron.ch> Date: Tue Jul 28 18:33:06 2009 +0200 Report error when declaring virtual methods as extern See bug 584400.
(In reply to comment #14) > In my opinion, having anything in the vfunc wrapper other than just a call to > the implementation is an abuse of the virtual function mechanism, I don't > really want to encourage these strange wrapper functions. > I agree. > If you need methods that work if the instance implements a particular interface > or not, use static methods and type checks. Falling back to something > completely different doesn't sound right. We might be able to achieve something > like what you want if we add extension methods or similar to Vala. > Thank you for the hints. I'll think about it.