Skip to content
Luke Pickering edited this page Jun 30, 2016 · 8 revisions

Date: 26th May 2016

Time: 12:00 - 13:00 UK

Room: 532 Blackett, 40-2-A01 CERN

Indico Link: https://indico.cern.ch/event/536541/

Vidyo link: https://vidyoportal.cern.ch/flex.html?roomdirect.html&key=jWovOD3i3Wr9oDDLFka32uHn48w

C++ bonanza

Ben

  • The keyword 'using' in classes and inheritance with functions from a base class.
struct TH1_CheckAxes:public TH1{
    using TH1::CheckConsistency;
};
  • Namespaces and in particular anonymous namespaces.
#include <anotherclass.h>

namespace {
    void SomeFunction();
}

int main(){
   SomeFunction();
   return 0;
}

anotherclass.cxx:

namespace{
void somefunction();
}
  • Preprocessor macros: X-macros
  • The keyword 'static' which has a shit-ton lot of different uses.
    • Like an anonymous namespace for free floating functions / variables
    • To create a class method (as opposed to an instance method)
    • Variables that are presisted between function invocations
  • Pass by reference not value!
void DoSomething( std::vector<int> vals); // Passes a copy of the vector
void DoSomething( const std::vector<int>& vals); // Passes a const reference to the vector => Quicker!

Luke's Random Thoughts... may be inane:

Finding missing symbols in libraries

#include <iostream>
#include <csignal>

#include "Math/SpecFuncMathMore.h"

struct Bla {
  Bla(double inp){
    std::cout << "Making new Bla -- " << inp << std::endl;
    Member = inp;
  };
  double Member;
};

int main() {

  std::cout << ROOT::Math::assoc_legendre(2,0,0) << std::endl;

  raise(SIGINT);

  Bla local_bla(1);

  Bla *dyn_bla = new Bla(2);

  new (&local_bla) Bla(3);

  new (dyn_bla) Bla(4);

}

Compile with g++ -g $(root-config --libs --cflags) foo.cxx

Will fail because needs libMathMore.so, (pretend you don't know that).

/home/luke/CC20160630/foo.cxx:16: undefined reference to `ROOT::Math::assoc_legendre(unsigned int, unsigned int, double)'
collect2: error: ld returned 1 exit status

Where does that symbol live!? Its ROOT so lets look there: for i in /home/luke/projects/t2k/vols/software/ROOT/Linux-x86_64/lib/root/*.so; do nm $i | grep "assoc_legendre"; if [[ "$?" == "0" ]]; then echo $i; fi; done

0000000000072169 T _ZN4ROOT4Math14assoc_legendreEjjd
/home/luke/projects/t2k/vols/software/ROOT/Linux-x86_64/lib/root/libMathMore.so
                 U _ZN4ROOT4Math14assoc_legendreEjjd
/home/luke/projects/t2k/vols/software/ROOT/Linux-x86_64/lib/root/libRooFit.so

err... where does it live ? nm --defined-only

0000000000072169 T _ZN4ROOT4Math14assoc_legendreEjjd
/home/luke/projects/t2k/vols/software/ROOT/Linux-x86_64/lib/root/libMathMore.so

with c++filt (ed: Phill -- nm has a demangle option -C)

0000000000072169 T ROOT::Math::assoc_legendre(unsigned int, unsigned int, double)
/home/luke/projects/t2k/vols/software/ROOT/Linux-x86_64/lib/root/libMathMore.so

Okay, lets edit our compile line: g++ -g $(root-config --libs --cflags) -lMathMore -L/vols/t2k/software/nd280/v12r1/GSL/v1r15p0n00/Linux-x86_64/lib -lgsl -lgslcblas foo.cxx

(Also needed gsl...)

Success!

Signals

#include <csignal>
 //...
raise(SIGINT);
 //...

Will send the same signal at ctrl+c to your program... which when in a debugger is a bit like a programatic breakpoint (i.e. you can continue from it). Do not leave these in production code (ever, at all).

Signal handlers are fun and useful: http://www.gnu.org/software/libc/manual/html_node/Signal-Handling.html

Placement new

  Type *t = new Type();
  new (t) Type(Something...);

Will only allocate memory once, the placement new operator just invokes the constructor on already allocated memory. Be sure to manually invoke the destructor of the instance you are overwriting!

  Type *t = new Type();
  t->~Type();
  new (t) Type(Something...);
Clone this wiki locally