CINT does not need member function declaration?

Hi,

I have the simple base class

[code]class TBase : public TObject
{
public:
TBase(TString T = “”);
};

TBase::TBase(TString FName)
{
printf(“Base: Called with ‘%s’\n”,FName.Data());
}

TBase::Print(Double_t D)
{
printf(“Called with %8.2f\n”,D);
}[/code]
(please notice that the Print() member function is not declared!).
The test script

{ gROOT->ProcessLine(".x TBase.C"); TBase A("Some"); A.Print(3.14); }
results in

[quote]root [11] .x derivedtest.c
Base: Called with ‘’
(class TBase)125198896
Base: Called with ‘Some’
Called with 3.14[/quote]
After this, a quite unexpected error message appears,

[quote]root [13] .x derivedtest.c
Error: unrecognized language construct FILE:C:\veghj\projects\root\ewa\TBase.C LINE:5
*** Interpreter error recovered ***
Error: Function TBaseA(“Some”) is not defined in current scope FILE:C:\veghj\projects\root\ewa\derivedtest.c LINE:4
Possible candidates are…
filename line:size busy function type and name
*** Interpreter error recovered ***[/quote]
i.e. the line

TBase A("Some");
in interpreted in this strange way; a CINT error I experienced several times. In this case it is because I added the line to the class definition

(without semicolon). I think this misleading error message should be eliminated, too.

In addition, this message proves that the function declaration is scanned; but it looks like it is neglected. (If I change the definition to
void Print(TString D);
nothing changes, so it looks like member function declarations neglected: a source of serious errors, see overloading and default parameter values.

Then I added the missing semicolon, so the class declaration is now

class TBase : public TObject { public: TBase(TString T = ""); void Print(Double_t D); };
The result, however, is unchanged.
Is this again a kind of extension by CINT?

Janos

Hi,

The problem is that you inherit from TObject which deoes define a function named Print. CINT probably should warn you about the case, we will try to add such a warning in the future.

But you should be aware of an additional problem. Currently interpreted class which inherits from a compiled class (like TObject) can not overload existing virtual function (we do not know how to patch the virtual table of the compiled class in a simple, low overhead, platform independent manner).

So if you actually need to derive from TObject, you should compile you class (easy to do with ACLiC: just add the proper include files and do:

Cheers,
Philippe

[quote=“pcanal”]Hi,

The problem is that you inherit from TObject which deoes define a function named Print. CINT probably should warn you about the case, we will try to add such a warning in the future.
[/quote]

Do you mean

virtual void Print(Option_t *option="") const; ?
I strongly hope CINT cannot mismatch the virtual method with string parameter with my non-virtual method with floating parameter. Or, does it?

Janos

Hi Janos,

I re-read your message and give some better answer :slight_smile:

Your first test [quote]“please notice that the Print() member function is not declared!”[/quote]works properly because indeed CINT is adding the ‘feature’ of letting you define the method outside the class declaration (so indeed this is an extension).
Your first error:

[quote]Error: unrecognized language construct FILE:C:\veghj\projects\root\ewa\TBase.C LINE:5 [/quote]could be improved.

[quote]In addition, this message proves that the function declaration is scanned; but it looks like it is neglected. (If I change the definition to
void Print(TString D); [/quote]Because of the above mention extension, this is equivalent to declaration both.

When developing, we always recommend that in doubt you compile your code using ACLiC (this will provide better message).

Cheers,
Philippe.

Hi Philippe,

I think what I have outside the class declaration, it is rather an implementation than definition. The definition is completely missing. Although I find it a rather unwanted and dangerous extension, I think it should be mentioned in the docs. It is too expensive to discover all these hidden extensions be myself.

If I understand correctly, CINT neglects the member function definitions (provided they are syntactically correct) and uses the function implementations instead. On the other hand, ACLiC collects the dictionary based on the header (i.e. class definition) only. A pretty good source of confusion, if the two differ. And, they might differ!
I also do not know what happens with the default parameters. They cannot be repeated (at least not according to C++ standard), so the interpreted and compiled program can work differently. If I repeat the default parameter, the compiler will produce redefinition error, if I do not write it in the member function definition, the dictionary will be wrong.

Reagrds

Janos

[quote]I also do not know what happens with the default parameters[/quote].
Humm … I missed this point? Can you regive me your example.

Philippe.