Trunk@40894

This is Ubuntu 10.04.3 LTS i686 with gcc 4.4.3 here …

  1. xrootd cannot be compiled - something about missing “__sync_fetch_and_add” blah blah
  2. after disabling xrootd I was able to compile ROOT, but …
  3. a perfectly legitimate macro (working well with ROOT v5-28-00-patches, for example) dies:

root [0] .L MyMacro.cxx++
Info in TUnixSystem::ACLiC: creating shared library /…/./MyMacro_cxx.so
Error in : Dictionary generation failed!
Info in : Invoking compiler to check macro’s validity
Info in : The compiler has not found any problem with your macro.
Probably your macro uses something rootcint can’t parse.
Check root.cern.ch/viewvc/trunk/cint/doc/limitati.txt for Cint’s limitations.

I tried to set gDebug = 9999, but there were no additional hints what failed.

Well, can you check if any macro at all can be compiled? If yes, you have to find minimal code to reproduce the problem, as soon as you can not give us your code (and data).

Some macros can be compiled (by ACLiC), some cannot.
As there is no verbose output what fails at all, I cannot give any more details for the moment.
I can only say that ROOT v5-28-00-patches has no problems with them (i.e. its ACLiC).

[quote=“Pepe Le Pew”]Some macros can be compiled (by ACLiC), some cannot.
As there is no verbose output what fails at all, I cannot give any more details for the moment.[/quote]

Can you, please, show the minimal macro which can not be compiled?

The current rootcint dies on:

#ifndef CINT
// “Data” is being initialized here (compiled code only)
const MyClass Data[] = { … , … , … };
const Int_t NData = (sizeof(Data) / sizeof(MyClass));
#else
// “dictionary” generation (“interpreted” code only)
const Int_t NData;
const MyClass Data[]; // current rootcint dies here
#endif

[quote=“Pepe Le Pew”]The current rootcint dies on:

#ifndef CINT
// “Data” is being initialized here (compiled code only)
const MyClass Data[] = { … , … , … };
const Int_t NData = (sizeof(Data) / sizeof(MyClass));
#else
// “dictionary” generation (“interpreted” code only)
const Int_t NData;
const MyClass Data[]; // current rootcint dies here
#endif[/quote]

If I was CINT, I would also die here. It’s a definition, not a declaration, and the size of array is unknown. What should CINT think about this? How to allocate a memory for something of unknown size?
(another question, how it worked before).

This code is always used as an ACLIC-precompiled macro.
This kind of tricks is needed for the rootcint when it is not able to parse the c++ code but it still needs to generate the dictionary (so, everything will properly be allocated and initialized by the compiler, CINT is not allowed to interfere).
I can assure you that both, the very old ROOT 5.18 and the recent ROOT 5.28, are able to get it right.
The newest rootcint from the trunk@40894 dies without any “verbose error message”.

Hi,

I can not reproduce the problem (but with gcc 4.4.5).

Can you try valgrind rootcint -f dict.cxx -c MyMacro.cxx linkdef.h

Cheers,
Philippe.

I’m afraid you are right.
I just tried to prepare a new short test macro and there was no problem either.
That means that in some cases this problem is lethal (rootcint dies with a segmentation fault) and in some others it is not (rootcint survives).
I am quite sure that the problem line is:
const MyClass Data[]; // current rootcint dies here
because if I remove it, I am able to “.L MyMacro.cxx++”.
Here’s the valgrind output for my “original macro” … does it help?

/MyWorkingDir$ valgrind rootcint “–lib-list-prefix=${PWD}/MyMacro_cxx_ACLiC_map” -f “${PWD}/MyMacro_cxx_ACLiC_dict.cxx” -c -p -I$ROOTSYS/include -I"${ROOTSYS}/include" “${PWD}/./MyMacro.cxx” “${PWD}/MyMacro_cxx_ACLiC_linkdef.h”
==3532== Memcheck, a memory error detector
==3532== Copyright © 2002-2009, and GNU GPL’d, by Julian Seward et al.
==3532== Using Valgrind-3.6.0.SVN-Debian and LibVEX; rerun with -h for copyright info
==3532== Command: rootcint --lib-list-prefix=/MyWorkingDir/MyMacro_cxx_ACLiC_map -f /MyWorkingDir/MyMacro_cxx_ACLiC_dict.cxx -c -p -I/…/root/include -I/…/root/include /MyWorkingDir/./MyMacro.cxx /MyWorkingDir/MyMacro_cxx_ACLiC_linkdef.h
==3532==
==3532== Invalid write of size 4
==3532== at 0x40FE0E0: G__basedestructrc (in /…/root/lib/libCint.so.5.31)
==3532== by 0x40FDEC3: G__basedestructrc (in /…/root/lib/libCint.so.5.31)
==3532== by 0x40FDEC3: G__basedestructrc (in /…/root/lib/libCint.so.5.31)
==3532== by 0x40FDEC3: G__basedestructrc (in /…/root/lib/libCint.so.5.31)
==3532== by 0x40FDEC3: G__basedestructrc (in /…/root/lib/libCint.so.5.31)
==3532== by 0x40FDEC3: G__basedestructrc (in /…/root/lib/libCint.so.5.31)
==3532== by 0x40FDEC3: G__basedestructrc (in /…/root/lib/libCint.so.5.31)
==3532== by 0x40FDEC3: G__basedestructrc (in /…/root/lib/libCint.so.5.31)
==3532== by 0x40FDEC3: G__basedestructrc (in /…/root/lib/libCint.so.5.31)
==3532== by 0x40FDEC3: G__basedestructrc (in /…/root/lib/libCint.so.5.31)
==3532== by 0x40FDEC3: G__basedestructrc (in /…/root/lib/libCint.so.5.31)
==3532== by 0x40FDEC3: G__basedestructrc (in /…/root/lib/libCint.so.5.31)
==3532== Address 0x5762960 is 8 bytes after a block of size 192 alloc’d
==3532== at 0x4024F20: malloc (vg_replace_malloc.c:236)
==3532== by 0x41D3DA5: G__allocvariable(G__value, G__value*, G__var_array*, G__var_array*, int, int, char const*, char*, int, Cint::G__DataMemberHandle&) (in /…/root/lib/libCint.so.5.31)
==3532== by 0x41E6F21: G__letvariable(G__FastAllocString&, G__value, G__var_array*, G__var_array*, Cint::G__DataMemberHandle&) (in /…/root/lib/libCint.so.5.31)
==3532== by 0x40AC7F4: G__define_var (in /…/root/lib/libCint.so.5.31)
==3532== by 0x4147507: G__exec_statement (in /…/root/lib/libCint.so.5.31)
==3532== by 0x410D72C: G__loadfile (in /…/root/lib/libCint.so.5.31)
==3532== by 0x4106153: G__main (in /…/root/lib/libCint.so.5.31)
==3532== by 0x806CB49: main (in /…/root/bin/rootcint)
==3532==
==3532==
==3532== HEAP SUMMARY:
==3532== in use at exit: 58,133 bytes in 6,027 blocks
==3532== total heap usage: 102,767 allocs, 96,740 frees, 8,733,193 bytes allocated
==3532==
==3532== LEAK SUMMARY:
==3532== definitely lost: 47,248 bytes in 5,981 blocks
==3532== indirectly lost: 588 bytes in 21 blocks
==3532== possibly lost: 728 bytes in 8 blocks
==3532== still reachable: 9,569 bytes in 17 blocks
==3532== suppressed: 0 bytes in 0 blocks
==3532== Rerun with --leak-check=full to see details of leaked memory
==3532==
==3532== For counts of detected and suppressed errors, rerun with: -v
==3532== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 27 from 8 )

Hi,

The problem might be triggered by the layout of the class MyClass. Can you send us a complete running example reproducing the problem?

Thanks,
Philippe.

I was finally able to “cut down” my source code (I hope I didn’t make any mistake) …
Try to “.x MyMacro.cxx++” using the attached files (strip “.txt” from their names first).
MyMacro.cxx.txt (284 Bytes)
MyClass.hxx.txt (475 Bytes)

Hi,

The memory management and allocation scheme in CINT has been improved such that now the code:// "Data" is being initialized here (compiled code only) const MyClass Data[] = { ... , ... , ... }; const Int_t NData = (sizeof(Data) / sizeof(MyClass)); does work in CINT and the (broken) code: // "Data" is being initialized here (compiled code only) const MyClass Data[]; const Int_t NData = (sizeof(Data) / sizeof(MyClass));no longer works (leads to be mismatch in allocation/deallocation). Arguably, we might be able to update CINT further to ‘remember’ properly that the array was not allocated (and hence not try to deallocate it). However we are currently focusing on cling and are unlikely to get around to implement such a fix in CINT.

Cheers,
Philippe.

Well, the “new memory management” still cannot parse, for example (i.e. you still need to “.x trial.cxx++”):

[code]#include

void trial(int i = 10)
{
int x[i];
int ii = 2 * i;
int xx[ii];

std::cout << "sizeof(x) = " << sizeof(x) << std::endl;
std::cout << "sizeof(xx) = " << sizeof(xx) << std::endl;

}
[/code]
Up to now I was able to “overcome” it using simple tricks.
Now things changed as I can see …

Going back to my original problem …
Will there be any difference in the rootcint dictionary (and so in the way CINT will see the compiled macro afterwards) if I replace “MyClass Data[];” with “MyClass *Data;”?
Of course, ONLY for the “dictionary” generation, the “compiled code” stays as it was (so there will be a “mismatch”, but maybe it’s enough safe).

#ifndef __CINT__ // "Data" is being initialized here (compiled code only) const MyClass Data[] = { ... , ... , ... }; const Int_t NData = (sizeof(Data) / sizeof(MyClass)); #else // "dictionary" generation ("interpreted" code only) const Int_t NData; const MyClass *Data; // current rootcint does NOT die here ("*Data" instead of "Data[]") #endif

BTW. In my first mail I mentioned that xrootd cannot be compiled, I hope you noticed.

[quote]Well, the “new memory management” still cannot parse, for example (i.e. you still need to “.x trial.cxx++”):

[code]#include

void trial(int i = 10)
{
int x[i];
int ii = 2 * i;
int xx[ii];

std::cout << "sizeof(x) = " << sizeof(x) << std::endl;
std::cout << "sizeof(xx) = " << sizeof(xx) << std::endl;

}
[/code]
Up to now I was able to “overcome” it using simple tricks.
Now things changed as I can see …
[/quote]

It’s PERFECT, if CINT does not want to compile this, since this is not a valid C++. If g++ can compile this, it’s only because g++ also compiles C (not C++) and such arrays exist in C.

So, first you are doing something illegal, later you complain that compiler/parser is doing something illegal
with you illegal code (crashes, formats you hard drive, etc).

First of all, what concerns my “original problem”, I do not want CINT to interpret it. I want ROOTCINT to parse it and create dictionary entries.
For the time being, I simply need to find another way of cheating ROOTCINT, as the “old / canonical” way of cheating no longer works.
Moreover, letting the newest ROOTCINT see the initialization does not work either, ROOT dies with a segmentation violation if I try “.x MyMacro.cxx” and ROOTCINT dies when I try “.x MyMacro.cxx++” (try the attached source code, strip “.txt” from their names first).

Second, what concerns my joke from the previous post, “variable-length automatic arrays” are a perfectly legitimate GNU C AND C++ extension (I write “AND”, as it is both for C and C++, there exist extensions specific only to C and others specific only to C++).
People are often using “extensions” without even knowing they are “non-standard”.
Starting with the c/c+±preprocessor capabilities, system macros, system (libc) functions, …

If you really care that much about the “standard”, take the ROOT source code and try:
make EXTRA_CFLAGS="-pedantic" EXTRA_CXXFLAGS="-pedantic"
We’ll see how far it brings you.
At my place it died while trying to compile “cint/cint/src/loadfile.cxx”.

And if you care even more … try:
make EXTRA_CFLAGS="-ansi -pedantic" EXTRA_CXXFLAGS="-ansi -pedantic"
At my place it died while trying to compile “cint/cint/src/g__cfunc.c” (which was just the 8-th file that was being compiled).
MyMacro.cxx.txt (368 Bytes)
MyClass.hxx.txt (619 Bytes)

The problem here is that people do not use extensions - they write ill-formed C++ code, they ignore what they were told or what they have read in books about how to specify arrays in C++ and g++ silently helps them and supports their heresy. So they use ROOT/G++ for years and years and suddenly they find out something new about the PRIMITIVE basics of the language they use, which they should learn in the first day they use C++. Well, many thanks to compiler or interpreter for this, better late, than never.
I can give you another example of bad CINT’s work - it permits implicit conversions between unrelated pointer types which can be the source of NASTY bugs - may be, somebody uses such conversion -is it extension of compiler bug now???

Many thanks for your advice, but I’ll decide myself how I compile ROOT or my code. As soon as CINT supports CORRECT syntax now, you’d better use THE CORRECT syntax. Of course, I do not know CINT’s internals, may be it’s still possible to support “extensions” - after all, CINT forced you to do tricks.
And of course, it should not be supported if you are the only user who does such tricks, or even there 10 such users.

May be, from the beginning you found BAD workaround and you were able to use the correct, legal syntax?

Just for curiosity, I compiled the new macro, which I attached in my previous post, using:
g++ -ansi -pedantic -W -Wall -O3 -I$ROOTSYS/include -c MyMacro.cxx
And the only problems that I got were:
root/include/Rtypes.h:153:43: warning: use of C99 long long integer constant
root/include/Rtypes.h:90: warning: ISO C++ 1998 does not support ‘long long’
root/include/Rtypes.h:91: warning: ISO C++ 1998 does not support ‘long long’
root/include/TString.h:525: warning: ISO C++ does not support the ‘ll’ gnu_printf length modifier
root/include/TString.h:533: warning: ISO C++ does not support the ‘ll’ gnu_printf length modifier
I find the last two the best.
Which one of these “used extensions” makes the ROOT die with a with a segmentation violation when I try “.x MyMacro.cxx”?

Again, CINT is NOT a full featured C++ interpreter. It has its own extensions. It has limitations. It’s is able to process a lot of the C/C++ source code, but there are cases in which one needs to cheat it. That’s fine with me. I just need to know how.

Anyhow, I don’t think that any discussions about the “standard” will bring me further.
It seems to me that I still need to hide the initializations from (ROOT)CINT.
So, will there be any difference in the rootcint dictionary (and so in the way CINT will see the compiled macro afterwards) if I replace “MyClass Data[];” with “MyClass *Data;”?
Of course, ONLY for the “dictionary” generation, the “compiled code” stays as it was (so there will be a “mismatch”, but maybe it’s enough safe).

[quote]So, will there be any difference in the rootcint dictionary (and so in the way CINT will see the compiled macro afterwards) if I replace “MyClass Data[];” with “MyClass *Data;”?
Of course, ONLY for the “dictionary” generation, the “compiled code” stays as it was (so there will be a “mismatch”, but maybe it’s enough safe).[/quote]

Well, I do not have linux/unix machine at the moment, so can not try. Can you just declare, not define your array of constants in CINT’s related block of code, and define and initialize it in C++ compiled code? I’m not sure what will happen, but it can work and it’s a legal code.

extern const YourClass array[];//and if this does not work due to some bizare CINT logic, specify the size of array. This is declaration. It does not require initializers (which are in compiled block)

Adding “extern” does not help. The newest rootcint dies, too (the old ROOT 5.18 and 5.28 are fine with it).
On the other hand, specifying a fixed size helps (no need to use “extern” in this case).

So, the newest rootcint will not accept:
extern const Myclass Data[]; // that declaration kills rootcint
but it will happily accept:
const MyClass Data[1]; // that definition is fine for rootcint

If I have to cheat, I’m not sure if I want “Data[1]”, I think I would really prefer “*Data”:
const MyClass *Data;
I just need to be sure that it’s “safe enough”.

Anyhow, it would be interesting if you tried to run my newest test macro (the one that kills both the root and rootcint) which was attached in my post of “Sat Sep 17, 2011 14:54” earlier today.
According to Philippe the current root and rootcint should be able to handle it without problems, but they are not.

Can it be that the problem is not with CINT at all? (ROOT was not built properly)
I’ll try your code tomorrow, but I have a trunk of ROOT.