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?

 cint@root.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@pcroot.cern.ch is the mailing list for ROOT/CINT framework. This
 mailing list is mixture of ROOT and CINT.

 rootdev@pcroot.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 <rpc/xdr.h>   // 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<chris@uxsrvc.tti-telecom.com>
  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<T>::iterator is defined as T*.

    vector<int> a(20); // a[0] to a[19]
    vector<int>::iterator first=a.begin();  //  &a[0]
    vector<int>::iterator last =a.end();    //  &a[20] one beyond the boundary

