After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 584400 - extern virtual/abstract member in an interface produces wrong ccode.
extern virtual/abstract member in an interface produces wrong ccode.
Status: RESOLVED NOTABUG
Product: vala
Classification: Core
Component: Code Generator
0.7.x
Other All
: Normal normal
: ---
Assigned To: Jürg Billeter
Vala maintainers
Depends on:
Blocks:
 
 
Reported: 2009-05-31 22:41 UTC by rainwoodman
Modified: 2009-07-29 02:40 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
remove static from _real functions for external virtual members (1.19 KB, patch)
2009-05-31 23:07 UTC, rainwoodman
none Details | Review
remove the function bodies for extern virtual members. (934 bytes, patch)
2009-05-31 23:08 UTC, rainwoodman
none Details | Review
compilation result of the test case (1.58 KB, text/plain)
2009-05-31 23:09 UTC, rainwoodman
  Details
test case (168 bytes, text/plain)
2009-05-31 23:10 UTC, rainwoodman
  Details
real cname as a ccode attribute (2.07 KB, patch)
2009-06-02 16:10 UTC, rainwoodman
none Details | Review
test for the real_cname(135822) (110 bytes, text/plain)
2009-06-02 16:11 UTC, rainwoodman
  Details
Test extern overriden methods. (206 bytes, text/plain)
2009-06-02 16:18 UTC, rainwoodman
  Details

Description rainwoodman 2009-05-31 22:41:51 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:
Comment 1 rainwoodman 2009-05-31 23:07:30 UTC
Created attachment 135693 [details] [review]
remove static from _real functions for external virtual members

very small fix.
Comment 2 rainwoodman 2009-05-31 23:08:06 UTC
Created attachment 135694 [details] [review]
remove the function bodies for extern virtual members.

another very small fix.
Comment 3 rainwoodman 2009-05-31 23:09:13 UTC
Created attachment 135695 [details]
compilation result of the test case

compilation result of the test case
Comment 4 rainwoodman 2009-05-31 23:10:51 UTC
Created attachment 135696 [details]
test case

test case
Comment 5 Jürg Billeter 2009-06-01 06:38:34 UTC
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.
Comment 6 rainwoodman 2009-06-01 07:41:30 UTC
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'.

Comment 7 Jürg Billeter 2009-06-01 07:55:21 UTC
Is the real issue for your use case that you need a fix for bug 546305?
Comment 8 rainwoodman 2009-06-01 09:12:16 UTC
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.
Comment 9 rainwoodman 2009-06-02 16:10:28 UTC
Created attachment 135822 [details] [review]
real cname as a ccode attribute
Comment 10 rainwoodman 2009-06-02 16:11:06 UTC
Created attachment 135823 [details]
test for the real_cname(135822)
Comment 11 rainwoodman 2009-06-02 16:18:25 UTC
Created attachment 135826 [details]
Test extern overriden methods.
Comment 12 zarevucky.jiri 2009-06-22 16:09:00 UTC
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.
Comment 13 rainwoodman 2009-06-23 01:54:50 UTC
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.
Comment 14 Jürg Billeter 2009-07-28 16:39:20 UTC
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.
Comment 15 Jürg Billeter 2009-07-28 16:51:23 UTC
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.
Comment 16 rainwoodman 2009-07-29 02:40:16 UTC
(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.