CINT C++ interpreter Frequently Asked Questions ############################################################################ # Can I embed my functions and classes into CINT? Yes, CINT is made particulary for this purpose. Please read README.txt, doc/makecint.txt, doc/ref.txt and other documentation. There are examples in demo/makecint directory. 'makecint' is a tool to embed user library into CINT C/C++ interpreter. User library can configured as DLL(Dynamic Link Library or Shared Library) and static library. If you use ROOT framework, you should read ROOT documentation. ############################################################################ # Can I embed CINT into my host application. Yes, you can do this. Please read README.txt, doc/makecint.txt(-m option), doc/ref.txt and other documentation. There is an example in demo/makecint/UserMain directory. If you use Windows, demo/Win32app directory contains a couple of interesting examples too. You can invoke CINT interpreter from your main program. CINT has API for this purpose. G__init_cint(), G__loadfile(), G__calc(), G__exec_text(), G__scratch_all(). Refer to doc/ref.txt for detail of those API. ############################################################################ # Where can I find documentation? The documentation is included in cint source distribution package. You have following files to start with. README.txt : general info, installation, etc... platform/README.txt : installation, multi-platform issues doc/cint.txt : cint man page doc/makecint.txt : makecint man page doc/ref.txt : reference manual doc/extlib.txt : guide for embedding user library doc/limitati.txt : limitations As you go deeper into subdirectories, README.txt exists in each important location. ############################################################################ # Is there CINT related news group or mailing list? root-cint@cern.ch is the mailng list for CINT. Send request to 'Majordomo@pcroot.cern.ch' containing following line for subscription. subscribe cint [preferred mail address] Archive for CINT mailing list can be accessed as follows. http://root.cern.ch/root/cinttalk/AboutCint.html roottalk@cern.ch is the mailing list for ROOT/CINT framework. This mailing list is mixture of ROOT and CINT. rootdev@cern.ch is a mailing list distributed for ROOT/CINT developpers. root-bugs@pcroot.cern.ch is an entry for ROOT/CINT bug reporting system. You can submit bug report to this e-mail address. ############################################################################ # Cint seems to have some limitation and difference from C++ standard. Cint accepts most of K&R and ANSI C/C++ language constructs. However it is not perfect. In fact, Cint is not aimed to be a 100% ANSI/ISO compliant C/C++ language processor. It rather is a portable script language environment which is close enough to the standard C++. Please use simple expression whenever possible to avoid problems. Limitations are decribed in doc/limitati.txt. ############################################################################ # Why cint does not support POSIX system calls, such as putenv, getpid, fork, by default. In order to guarantee thorough portability among different computer platforms, cint only supports what is defined in ANSI/ISO C/C++ standard. Anything out of ANSI/ISO standard is not included in cint default configuration. ############################################################################ # Can I use POSIX system calls in the interpreter? Yes, you can. With an optional library built under lib/posix directory. Subset of POSIX.1 system calls are defined in lib/posix/posix.h. If you run setup script, include/posix.dll will be created. This DLL is loaded with the include/unistd.h standard header. If you use ROOT/CINT framework, you should use TSystem class which provides generic OS interface. ############################################################################ # Can I use Win32 API in the interpreter? Yes, you can. With an optional library under lib/win32api directory. Subset of Win32 API is defined in lib/win32api/winfunc.h. If you run setup.bat script, include/win32api.dll will be created. This DLL is loaded with the include/windows.h standard header. If you use ROOT/CINT framework, you should use TSystem class which provides generic OS interface. ############################################################################ # Can I use STL in the interpreter? Yes, you can, with some limitations. Interpreting STL: * Cint source package goes with an old STL (HP reference implementation) which is in stl directory. You can interpret string, vector and list containers and several generic algorithms. Using precompiled STL containers: * Small subset of precompiled STL containers can be built under lib/dll_stl directory. Read lib/dll_stl/README.txt and run setup script. You will have stl/vector.dll, stl/list.dll, stl/deque.dll, etc... You can precompile STL containers by yourself too. Simple example is in demo/makecint/stl directory. STL dummy headers are in lib/prec_stl directory. Supported containers: string, vector, list, deque, map, set, multimap, multiset, stack, queue valarray (VC++ BC++ only) Supported Platforms: OS Compiler STL implementation Linux2.0 + egcs + SGI HP-UX10.2 + aCC + RogueWave for HP-aCC HP-UX11.0 + aCC + RogueWave for HP-aCC Solaris5.7 + CC5 + SGI IRIX6 + KCC + 1997 Modena Software WinNT/9x + VC++ + P.J. Plauger WinNT/9x + C++Builder3.0 + RogueWave for BC++ ############################################################################ # I have problem using iostream library on some platforms There are several versions of iostream library support on CINT. 1) Precompiled ANSI C++ 3.0 iostream (old) This version is currently used with most of the compiler. ANSI C++ 3.0 is a old C++. Following compilers usethis version. Win32 Visual C++, Symantec C++, old Borland C++ Linux gcc,egcs FreeBSD gcc BSDOS gcc HP-UX CC,aCC,gcc Solaris SUNWspro/CC,gcc AIX xlC,gcc SGI CC,gcc Alpha cxx,gcc etc... 2) Precompiled template based iostream (new) Template based iostream library is supported only with C++ Builder at this moment. Win32 C++ Builder3.0 SGI IRIX6 KAI-CC 3.3 (sgi6.kcc) Alpha OSF1 KAI-CC 3.3 Linux KAI-CC 3.3 SunOS KAI-CC 3.3 Extending this support for other compiler is possible but not easy. Detail of template based library is still not quite uniform among different compilers. 3) Interpreted fake iostream Precompiled iostream library may not be supported for some compilers yet. Those compilers are the newest ones and support only the template based iostream. CINT provides fake iostream version which is interpreted. The fake version only supports limited functionality. ############################################################################ # I sometimes have problem using iostream in ROOT/CINT Please load iostream.h in rootlogon.C. For example, { // rootlogon.C printf("\nWelcome to the ROOT tutorials\n\n"); printf("\nType \".x demos.C\" to get a toolbar from which to execute the demos\n"); printf("\nType \".x demoshelp.C\" to see the help window\n\n"); G__loadfile("iostream.h"); // ADD THIS LINE IF THERE ISN'T } This will solve the problem in most of the case. Note: ROOT/CINT is the biggest CINT application which a framework for highenergy physics research. It is made by Rene Brun, Fons Rademakers, Valery Fine, Nenad Buncic. ############################################################################ # I have problem when using system include files # I have problem with '#include <[system_include_file]>' Every C/C++ processing system has its' own standard header file set. Normally, system header files include platform dependent information which can not be processed by other C/C++ processor. Cint version of system include files exist under $CINTSYSDIR/include and $CINTSYSDIR/stl directories. These directores includes ANSI-C headers ANSI/ISO C++ headers and several of POSIX, Windows related headers. Other system header files are missing. If you try to include such header, cint reads it from compiler's standard include directory, which is in many cases /usr/include. Because the header includes platform dependent expression which cint can not read, more than likely you will find problem. You can avoid reading non cint defined header files by using '#ifndef __CINT__' or '#ifndef __MAKECINT__'. For example, #ifndef __MAKECINT__ #include // compiler reads this header else #include "xdrdummy.h" // cint reads this header #endif You need to create xdrdummy.h which includes dummy interface to the system header. ############################################################################ # Cint does not work very well with #define macros. Is this a bug? For interactive convenience, cint parses macro and ordinaly C/C++ syntax at same time. This makes it difficult to handle preprocessor macros. Please understand, cint has limitation in preprocessor macros. (Refer to doc/limitati.txt) You can eliminate define macro limitation by using -p or -P option. Cint invokes C/C++ preprocessor before interpretation. Name of the preprocessors are specified in $CINTSYSDIR/MAKEINFO file. ############################################################################ # Can I inherit precompiled class from an interpreted class? # Virtual function sometimes does not work properly. # Explicit virtual function call does not work properly with precompiled class Cint supports class inheritance and virtual function calls in almost full C++ spec both within interpreted classes and precompiled classes. But there is fundamental difficulty in mixing interpreted/precompiled virtual functions. You could inherit precompiled class from an interpreted class, however, virtual function calls do not work properly. Every C++ compiler has proprietary Virtual Function Table format which is heavily implementation dependent. It is impossible for cint to match VTBL format of every C++ compiler. Cint has its'own virtual function resolution mechanism. So, virtual function or virtual base class can only be resolved within interpreted classes or precompiled classes. '#pragma link C++ class+protected" statement helps you to access protected members from the interpreter, however, it will not help virtual function resolution. There exist other C++ interpreter which allows virtual function resolution accross the interpreted/precompiled class boundary. But they severly sacrifice portability among different OS and compiler. Cint does not do this because portability is the primary importance to its concept. There is another case that virtual function of a precompiled class does not work properly. If you call virtual function of a precompiled class with scope operator, polymorphic resolution should be disabled and given specific function should be called. However in cint, you can not disable polymorphic resolution of a precompiled virtual function. This leads to calling wrong function if base and derived classes are both precompiled. New progress: - True virtual function resolution in mixed interpreted/precompiled-class environment is supported by STUB. Base class and interface of derived class have to be precompiled and derived class member function can be interpreted. Please find example in demo/makecint/Stub2 directory. ############################################################################ # sizeof() operator for class/struct returns inconsistent value between # compiled and interpreted program Every C/C++ processing system has unique class/struct member alignment rule. Cint has itsown rule , so does the compiler you use. If you interpret a class/struct definition and look at size and member offset alignment, it will be different from compiled version because of the difference in member alignment rule. If you precompile the class/struct definition, makecint/rootcint mirrors the size and the member offset of the precompiled class/struct. So the size and the offset will match. If size and offset consistency is important it is recommended to precompile class/struct definition. Instantiation of the precompiled class/struct can be done from interpreter. Created object has the same size and offset as the compiled object. ############################################################################ # Alignment of class/struct member is inconsistent between compiled and # interpreted program Same as above ############################################################################ # scanf, fscanf, sscanf functions has limit in number of arguments. scanf, fscanf and sscanf are implemented in strange way. If you give many arguments to those functions, cint displays error message and number of arguments you can give. The number includes the file pointer and formating string arguments, not only the input pointers. Use of ifstream, istrstream is recommended. ############################################################################ # Cint does not work and complains it can't find MAKEINFO file. Cint sometimes reads $CINTSYSDIR/MAKEINFO file for file name extention and preprocessor name. If you get this message, the reason is either * You do not set CINTSYSDIR environment variable. Please set CINTSYSDIR the directory you installed cint. * You did not install CINT properly and MAKEINFO file is missing. There are example of MAKEINFO files in platform directory. Please copy appropeate one as $CINTSYSDIR/MAKEINFO. Refer to platform/README. ############################################################################ # In most cases cint runs fast, but a small change makes it very slow. Why? Cint uses incremental bytecode compilation technique. The bytecode compiler has size and syntax limitations. When you hit that limitation, cint runs 10-20 times slower. Refer to doc/bytecode.txt for the detail. You can use -v command line option or '.debug' command for monitoring bytecode status. In case you see strange behavior, please check bytecode status with this feature. ############################################################################ # I have trouble precompiling namespace using makecint You need to define special #pragma to precompile namespace. By default, cint turns off linkage of nested classes and typedefs. Add following lines at the end of your header file. #ifdef __MAKECINT__ #pragma link C++ nestedclass; #pragma link C++ nestedtypedef; #endif Or #ifdef __MAKECINT__ #pragma link off all functions; #pragma link off all globals; #pragma link off all classes; #pragma link C++ nestedclass; #pragma link C++ nestedtypedef; #pragma link C++ namespace YOUR_NS_NAME; #pragma link C++ class YOUR_NS_NAME::YOUR_CLASS_NAME; #pragma link off function YOUR_NS_NAME::YOUR_FUNC_NAME; #pragma link C++ function YOUR_NS_NAME::YOUR_FUNC_NAME; . . #endif Please refer to doc/ref.txt. ############################################################################ # Can I turn on/off the bytecode compilation? Yes, you can. With '-O' command line option and 'O' debugger command. Refer to doc/cint.txt or cint online help. ############################################################################ # Can I get Cint binary for specific computer platform? Cint runs on nearly 20 different computer platforms and more than 40 compiler-OS-hardware combinations. Distributing binary package for all combination is almost impossible. Only source package and Windows binary packages are distributed from the Cint web page. Binaries for other platforms are available with CERN's ROOT package. ROOT binary packages include cint executable as root/bin/cint. ############################################################################ # Can I re-distribute cint source and/or binary? Yes, you can. License term is described in COPYING file. ############################################################################ # I want to make use of CINT parser for C/C++ syntax analysis CINT does not have parser as separate subsystem. So, it is not feasible to separate parser from CINT and use it in other software. I recommend looking into other sources. ############################################################################ # I want to understand CINT source code and want to make modification CINT has many legacy code. Inside CINT is quite messy. I do not recommend looking into the source code unless you have desparate reason. Fermi-Lab is trying to have a couple of researchers for reengineering of CINT. With this effort, I hope visibility and maintainability of CINT improves. ############################################################################ # Can CINT work in multi-thread environment? Cint is basically not multi-thread safe. However, there are a couple of techniques to emulate multi-threading. 1) Use fork() and shared memory If you use Linux or UNIX, you can use fork() system call and shared memory to emulate multi-threading. fork() example is shown in demo/mthread/fork.cxx and shared memory example is shown in demo/ipc directory. 2) Use system() and shared memory If you do not have much data to share between the threads, you can consider using system() function to start another Cint process and share data using shared memory. This is not a cool solution. But, this could solve your problem. 3) Compile background job and run it in other thread As long as you have only one CINT thread, you can split other precompiled jobs in different threads. Compile your background job as DLL using makecint, load it and run that background by threading function. On Windows-NT/9x, cint supports CreateThread() Win32 API in lib/win32api library. You can start precompiled threads from the interpreter. Please be careful about using CreateThread, a small mistake can crash MS-Windows. Example is shown in demo/mthread directory. On Linux or UNIX, cint supports pthread_create in lib/pthread library. You can start precompiled threads from the interpreter. Example is shown also in demo/mthread directory. 4) Use multi-thread safe libcintX.so/libcintX.dll This solution is proposed by Christoph Bugel and his collegue in TTI-telecom. This is a pretty smart solution. Cint core can be configured as a shared library libcint.so or DLL libcint.dll. If we have multiple copies of this library and load them independently, a dynamic loader thinks they are different libraries and keeps static variable independent. This way, we can run multiple Cint cores simultaneously in one process. This solution is experimentally supplied for Linux RH6.2 and Windows VC++6.0. For Linux, you need to install Cint using platform/linux_RH6.2_mtso. For Windows, add G__MULTITHREADLIBCINT macro at the beginning of G__ci.h and install Cint normally. Example is shown in demo/multilibcint directory. The implementation is quite experimental and there remains many issues. For example, on Linux, segmentation violation occurs if you unload shared libraries while Cint is running in other thread. ############################################################################ # Cint and compiled code yields different results handling string constants. For users convenience, Cint allows following operations. Those operations are potentially illegal in standard C/C++. Those are allowed for writing very short script when a user does not want to care much about correct syntax. - Direct comparison of string constants Following code is a valid C/C++ code, however, its' behavior is not guaranteed by C/C++ standard. Cint somehow evaluates (p=="abc") as true because of its' string constant management algorithm. However, it is not recommended to use this kind of expression in many locations because of essential incompatibility of operation. char *p = "abc"; if(p=="abc") printf("true\n"); // true You also need to notice that following expression is evaluated as false. char *p = "abc"; char buf[100]; sprintf(buf,"a%s","bc"); if(buf=="abc") printf("true\n"); // false - Using string constant in switch statement Cint allows potentially illegal switch statement as follows. This is a Cint's unique extention which causes compilation error in C/C++ compilers. char *p="abc"; switch(p) { case "abc": printf("match abc\n"); break; case "def": printf("match def\n"); break; default: printf("unmatch\n"); break; } ############################################################################ # Is Cint included in any of the standard Linux distribution package? Yes, SuSE includes Cint in their Linux distribution. Also, a couple of people are looking at the same thing for Debian GNU/Linux. This work is not completed yet. ############################################################################ # Can we install Cint binary only? Yes. First, you need to get Cint source package and compile it with setup script as described in README.txt and platform/README.txt. Then, run INSTALLBIN script to install binary only. It is recommended to set OTHMACRO = -DCINTSYSDIR=\"[binary_install_dir]\" in platform dependency file. This macro turns on a few feature that is suitable for binary only installation. ############################################################################ # Do we need include/*.dll and stl/*.dll files for using Cint You can use Cint without those files. However, those files expand Cint capability. So, I recommand to have those file. For more details, refer to include/README.txt and stl/README.txt. ############################################################################ # History of DLL(shared library) binary incompatibility Time to time, change in Cint source causes binary incompatibility of DLL or shared library. Here, I'll list up past history of DLL binary incompatibility. ..... 5.14.49 - 5.14.54 5.14.55 - 5.14.62 5.14.63 - 5.14.68 5.14.69 5.14.70 - 5.14.71 5.14.72 - 5.14.xx After 5.14.72, minor version will be incremented when DLL becomes binary incompatible. 5.15.XXX Basically, 5.15.XXX keeps binary compatibility. However, if you use C++ exception and/or Run Type Type Identification, you may find a problem. I recommend to re-generate and re-compile all interface method (or dictionary) for each Cint release. ############################################################################ # My compiler handles 'char' as 'unsigned char'. And CINT seems to depend that # 'char' is signed. What can I do? 'char' must be 'signed char' for CINT. If your compiler handles 'char' as 'unsigned char' by default, there are 2 solutions. 1. Add '-DG__SIGNEDCHAR' option to SYSMACRO in platform dependency file Before you install CINT, edit your platform dependency file that it has -DG__SIGNEDCHAR in SYSMACRO variable. This flag changes 'char' to 'signed char' in CINT header file. 2. Use your compiler's 'signed char' option IBM with xlc/xlC : -qchars=signed IBM s390 with gcc : -fsigned-char SGI with gcc : -fsigned-char SGI with CC : -signed SGI with KCC : --signed_chars ############################################################################ # CINT checks array boundary, but check is not rigid enough. CINT checks array boundary at run-time for interpreted code. For example, $ cint cint> { int a[20]; } cint> p a[19] (int)0 cint> p a[20] (int)0 cint> p a[21] Error: Array index out of range a[21] -> [21] valid upto a[19] Valid index range of array 'a' is 0 to 19. You may wonder why a[20] is not an error. The reason why is that ANSI-C standard requires C language processor to allow access of an array element one beyond the boundary. In this case, a[20] must be allowed. Existing C/C++ code in the world depends on this behavior. For example, C++ standard library depends on it if if vector::iterator is defined as T*. vector a(20); // a[0] to a[19] vector::iterator first=a.begin(); // &a[0] vector::iterator last =a.end(); // &a[20] one beyond the boundary