-- JuanCastillo - 25 Mar 2008

Passing arguments to our main

Once we execute our program, it can takes the argument we pass to it via keyboard

  int main(int argc, char **argv){
            if(argc < 5) {
            usage();
            return -1;
        }
        Int_t FileNumber = atoi(argv[1]);
        TString RootOut  = argv[2];
        Double_t  muestras  = atof(argv[3]);
        TString SetInfo  = argv[4];

If we call our program test, we should run it like this:
test 12 something 6.5 anotherthing
Where our program is =test and the rest are parameters in order

ALERT! NOTE: If you have a ROOT TApplication object defined, like this:
TApplication *myApp = new TApplication("myApp",&argc,argv);
put it AFTER the variable filling, that is, after the last parameter filled from argv.
Otherwise some parameters you take (like the integer), some not.

How to compile a simple code file

Our compiler in the examples below is g++.

g++ -o name code.cpp
  • An executable called name.out is generated compiling code.cpp
g++ -c name code.cpp
  • An object file code.o will be generated, appart from the exexutable.
g++ -Wall name code.cpp
  • "Warning all"
g++ -pedantic name code.cpp
  • The ANSI non-conformity will be displayed.

You can check the typical compiler options here

Using makefiles

If you know already about makefiles, maybe you should check first make-Online Guide for Unix/Linux

Checking the existence of one library

You will display a message on the screen asking you to make another project, and info about in which folder you should "make".
The missing library is extlib.
You can check it exists doing locate.
$locate Mylib.so
locate returns the paths to libraries with this name. The library path must be in LD_LIBRARY_PATH and it must be in the library database. In our case, we define also EXT_PATH containing the library path.

all: testmsg myprog    
# myprog : executable
myprog:  ${EXT_PATH}/Linux/extlib.$(DllSuf) \
         myprog.cpp 
         @echo "Linking $@ .........."
         $(C++) -o $@ $(C_FLAGS) $(ALL_INC) $^ $(ALL_LIB) 
         @echo "Everything is OK !"
testmsg: 
      @test -e ${EXT_PATH}/Linux/extlib.$(DllSuf) || \
      echo " *** ERROR *** Missing library: make first:${EXT_PATH}

ALERT! NOTE: Be careful with the tabs or you will obtain:
[make: * [myprog] Segmentation fault]

After typing make you will display your error message:
* ERROR * Missing library: make first:/path/
if the library is not there, even if the executable is already generated.

Header files organization

How to avoid reloading headers

If you reload a header the compiler will throw an error: redefinition about the class defined on the reloaded header. It's good to communicate to the compiler that you want to load the header only the first time they're compiled.
There are 2 methods of doing that.

Using preprocesor directives

In the header of your class Object, write:

       #ifndef _OBJECT_H_
       #define _OBJECT_H_
       ...
       class Object
       {
            //class body
        };
       #endif

Using pragma once

This is also a preprocessor directive, but more effective. Unfortunately it's not yet standart. Just write in your class header #pragma once .
The compiler will not open the file if it was already added to compilation. The difference with an #ifndef mechanism is that #ifndef is opening the file, and afterward not including it, so a pragma is faster.

General rule for headers

Let's call your class header Object.h.
If you want to use an Ext object/pointer defined in an external header Ext.h:

  • If you define in Object.h a member object Ext, include there Ext.h.
  • If you define in Object.h a pointer object *Ext, forward declare the class Ext and include the header in the code file.

ALERT! NOTE: Forward declarations are always faster than includes for pointers.

Interlinked objects

We have 2 alternatives:
  • 1. Include all the headers needed for a funtion in each function code file (economic for the compiler).
  • 2. Include all headers needed in the class header file, and in the class code file only the class header (less faster).
The option 2 is used due to the power of our actual machines.
Assume the File class has a member gets(String &destination), while the class String has a member function getLine(File &file). The (partial) header file for the class String must be:

    #ifndef _String_h_
    #define _String_h_
    #include <project/file.h>   // to know about a File
    class String
    {
        public:
            void getLine(File &file);
    };
    #endif

And similarly we need to do for the class File if we don't want to load the headers more than once.
Topic revision: r5 - 2008-04-17, JuanCastillo
 
This site is powered by FoswikiCopyright © by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding GSI Wiki? Send feedback
Imprint (in German)
Privacy Policy (in German)