====== Howtos and Tips ====== ===== System ===== For details on functions search in the man page (''man '' or ''man -a '' if there is also a unix command with same name), or search the web. ==== Catching signals ==== => C and C++. You can catch ctrl-c or other signals, for example to clean up things before to quit. #include void function_upon_sig (int sig __attribute__((unused))) { // write what you want to do here exit(0); } int main() { signal(SIGINT, function_upon_sig); // ctrl-c signal(SIGTERM, function_upon_sig); signal(SIGHUP, function_upon_sig); signal(SIGALRM, function_upon_sig); } You can see a complete list of all signals [[http://developer.spikesource.com/wiki/index.php/Errors:Signals|here]]. You should only use "async-signal safe" functions in the handler to avoid deadlocks (async-signal safety is stronger than thread safety, because the main program is completely interrupted until the handler has terminated). For example, ''printf'' is not safe, but ''write'' is, so you should write text on the terminal using ''write(STDOUT_FILENO, text, text_length);'' (more details [[http://www.cocoadev.com/index.pl?SignalSafety|here]]). You can also change the signals actions with the [[http://www.opengroup.org/onlinepubs/007908799/xsh/sigaction.html|sigaction function]]. ==== Timer ==== #include unsigned int alarm(unsigned int seconds); will trigger signal SIGALRM x seconds later that you can catch (see [[#catching_signals]]). If you need automatic repetition and/or sub-second precision, you can use: #include int setitimer(int whichtimer, const struct itimerval *value, struct itimerval *ovalue); ==== Waiting event ==== Monitor multiple file descriptors. #include int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout); ==== Posix Threads ==== #include void *threadFunction(void *threadid) { printf("%d: Hello World!\n", threadid); pthread_exit(NULL); } int main (int argc, char *argv[]) { pthread_t threadId; int threadData = 42; if (pthread_create(&threadId, NULL, threadFunction, (void *)threadData) != 0) { printf("thread creation failed"); exit(1); } return 0; } FIXME join sem etc ==== Change program owner ==== pwd = getpwnam("cyril"); if (pwd) { setgid(pwd->pw_gid); setuid(pwd->pw_uid); } But it doesn't really work to start shell commands, you should use ''sudo'' too: system("sudo -u cyril ); system("sudo -u cyril /bin/sh -c '; '); ===== Formatting IOs (iomanip) ===== => C++ #include for everything in this section. === Color === std::cout << "normal text, " << "\033[1;33m" << "colored text, " << "\033[1;00m" << "normal text" << std::endl; ^ Code ^ Effect ^ ^ Code ^ Effect ^ | ''\033[1;00m'' | normal white | | | | | | | | ''\033[1;29m'' | bold white | | ''\033[0;29m'' | normal white | | ''\033[1;30m'' | bold grey | | ''\033[0;30m'' | normal grey | | ''\033[1;31m'' | bold red | | ''\033[0;31m'' | normal red | | ''\033[1;32m'' | bold green | | ''\033[0;32m'' | normal green | | ''\033[1;33m'' | bold yellow | | ''\033[0;33m'' | normal yellow | | ''\033[1;34m'' | bold blue | | ''\033[0;34m'' | normal blue | | ''\033[1;35m'' | bold purple | | ''\033[0;35m'' | normal purple | | ''\033[1;36m'' | bold cyan | | ''\033[0;36m'' | normal cyan | === Floating point precision === double x = 32.14554; std::cout << "Double with 3 significant digits : " << std::setprecision(3) << x << std::endl; // 32.1 === Alignment === std::cout << std::setw(10) << "hello"; // "hello " std::cout << std::setfill('.') << std::setw(10) << "hello"; // "hello....." std::cout << std::right << std::setw(10) << "hello"; // " hello" === White spaces === To get all characters while they are white spaces. std::cin >> std::ws >> buffer; // "\r\n pouet" -> "pouet" ===== C/Cpp Preprocessor ===== To stop the compilation and print a message : #error Cannot compile To just print a message : #warning Possible problem To get a macro argument as a string : #define ASSERT(x) if (x == NULL) printf("Pointer %s NULL", #x); Macro with variable argument count (C99 only) : #define ERROR(msg, ...) fprintf("ERROR:%s:%d# ", __FILE__, __LINE__, ## __VA_ARGS__); You can also use the ''PRETTY_FUNCTION'' but it is not standard: #define ERROR(msg, ...) fprintf("ERROR:%s:%d %s# ", __FILE__, __LINE__, __PRETTY_FUNCTION__, ## __VA_ARGS__); Get the type of an argument : #define abs(x) ({ typeof(x) xx=(x); xx>0 ? xx : -xx; }) ===== Conversions with string ===== === From * to string === => C++ #include std::ostringstream oss; oss << 565; std::cout << oss.str() << std::endl; => C & C++ #include char s[128]; sprintf(s, "%d", 565); === From string to * === => C & C++ #include int i = atoi("562"); long l = atol("4500294"); double f = atof("4.546643"); ===== #define in compiler command ===== You can define names for the preprocessor from the command line (or the makefile) instead of the source file (''#define name''). It can be very useful. ^ Command ^ Equivalent in source file ^ | ''-D name'' | ''#define name'' | | ''-D name=value'' | ''#define name value'' | | ''-U name'' | ''#undef name'' | g++ foo.cc -o foo -D BAR=3 ===== Function pointers ===== The full test program is available [[http://www.rez-metz.supelec.fr/wiki/lib/exe/fetch.php/users:cyril:programming:function_pointers.cpp.txt|here]] === Normal fn === int fonction(double x, bool b); // declaration of the function int (*pf)(double,bool); // declaration of the pointer to function pf = &fonction; // initialization of the pointer (*pf)(9,true); // call of the function through the pointer Using ''typedef'': int fonction(double x, bool b); // declaration of the function typedef int (*fnIdb)(double,bool); // declaration of pointer type fnIdb pf = &fonction; // declaration and initialization of the pointer (*pf)(9,true); // call of the function through the pointer === Static member fn === Static member functions behave the same way than normal functions. class ClasseS { public: static int fonction(double x, bool b); }; // declaration of the function int (*psf)(double,bool); // declaration of the pointer to the function psf = &ClasseS::fonction; // initialization of the pointer (*psf)(5,true); // call of the static member function through the pointer === Non virtual member fn === Member functions have a hidden parameter (a pointer to ''this''), so the pointer needs an object to call the function. If the member function is non virtual, the address of the member function is the same for all objects. class Classe { public: int fonction(double x, bool b); }; // declaration of the function int (Classe::*pcf)(double,bool); // declaration of the pointer to function pcf = &Classe::fonction; // initialization of the pointer Classe classe; (classe.*pcf)(9,true) // call of the member function through the pointer === Virtual member fn === The syntax is the same as for non virtual member functions, and the pointer points to the place in the object where the address of the function is stored, so that it always points to the right function. class Classe { public: int fonction(double x, bool b); }; class Classe2 : public Classe { public: int fonction(double x, bool b); }; int (Classe::*pcvf)(double,bool); // declaration pcvf = &Classe::fonction; // initialization Classe *classe1 = new Classe(), *classe2 = new Classe2(); (classe1->*pcvf)(9,true) // calls Classe::fonction (classe2->*pcvf)(9,true) // calls Classe2::fonction ===== Cast overloading ===== === Cast from === This is done with constructors : class FixedPoint { unsigned int data; public: FixedPoint() { data = 0; } FixedPoint(int x) { data = x<<8; } Fixedpoint(double x) { data = (unsigned int)(x * (1<<8)); } }; double pi; FixedPoint pif; pi = 3.14; pif = pi; // it works, FixedPoint(double) is called for the cast === Cast to === The syntax is simple : class FixedPoint { unsigned int data; public: ... operator double() { return data / (double)(1<<8); } }; double pi; FixedPoint pif(3.14); pi = pif; // it works, double() is called for the cast === Template cast === Imagine the following situation : template class Pixel { T r,g,b; public: template inline Pixel& operator=(Pixel &pix) { r=pix.r; g=pix.g; b=pix.b; return *this; } }; Pixel pix1; Pixel pix2; pix2 = pix1; // it works, because operator= and cast are simultaneously overloaded that way Of course it works only if there is a possible cast from N to T. You can do the same with all operators (+,+= ...). ===== Operators overloading ===== It is painful to remember all declarations of operators overloading, then here they are : #include // for stream operators class Object { int a,b; public: Object(int a, int b) : a(a), b(b) {} // You MUST overload copy constructor and operator= if you allocate memory in your object Object(Object &o) : a(o.a), b(o.b) {} Object& operator= (const Object &o) { a=o.a; b=o.b; return *this; } // this is for +, but idem for all homogeneous binary operators : -,*,/, ... Object operator+ (const Object &o) const { return Object(a+o.a, b+o.b); } Object& operator+=(const Object &o) { a+=o.a; b+=o.b; return *this; } // this is for *, but idem for all heterogeneous binary operators : /,<<,>> ... Object operator* (int x) const { return Object(a*x, b*x); } Object& operator*=(int x) { a*=x; b*=x; return *this; } // stream operators should not be members, declare it friend to access protected data friend std::ostream& operator<<(std::ostream& os, const Object &o); friend std::istream& operator>>(std::istream& is, Object &o); }; //.cpp std::ostream& operator<<(std::ostream& os, const Object &o) { os << ...; return os; } std::istream& operator>>(std::istream& is, Object &o) { while (is >> ...) ... return is; } ===== Operators precedence ===== ^ Precedence ^ Operator ^ Name ^ Associativity ^ | 17 | '':: ::'' | scope resolution / global | R/L | | 16 | ''() ()'' | function call / value construction | L/R | | | ''[]'' | subscripting | L/R | | | ''. %%->%%'' | member selection | L/R | | | ''++ %%--%%'' | post increment/decrement | R/L | | 15 | ''()'' | type cast | R/L | | | ''sizeof'' | size of type or object | R/L | | | ''& *'' | address of / dereference | R/L | | | ''~ !'' | bitwise complement / logical not | R/L | | | ''+ -'' | unary plus and minus | R/L | | | ''++ %%--%%'' | pre increment/decrement | R/L | | | ''new'' ''delete'' ''delete[]'' | create / destroy / destroy array | R/L | | 14 | ''.* %%->*%%'' | member selection | L/R | | 13 | ''* / %'' | multiply / divide / modulo | L/R | | 12 | ''+ -'' | plus / minus | L/R | | 11 | ''%%<< >>%%'' | bit shifting | L/R | | 10 | ''< %%<=%% > >='' | comparison | L/R | | 9 | ''== !='' | comparison | L/R | | 8 | ''&'' | bitwise and | L/R | | 7 | ''^'' | bitwise exclusive or | L/R | | 6 | ''|'' | bitwise inclusive or | L/R | | 5 | ''&&'' | logical and | L/R | | 4 | ''||'' | logical inclusive or | L/R | | 3 | ''?:'' | conditional expression | R/L | | 2 | ''= += -= *= /= %='' | assignments | R/L | | | ''%%<<= >>=%% &= ^= |='' | | | | 1 | ''throw'' | throw exception | R/L | | 0 | '','' | comma | L/R | ===== Types ===== ^ Type ^ Size ^ Range ^ Precision ^ | char | 1 byte | -128 to 127 | 1 | | unsigned char | 1 byte | 0 to 255 | 1 | | short | 2 bytes | -32768 to 32767 | 1 | | unsigned short | 2 bytes | 0 to 65535 | 1 | | int | 4 bytes | -2 147 483 648 to 2 147 483 647 | 1 | | unsigned int | 4 byte | 0 to 4 294 967 295 | 1 | | long (int) | 4 bytes | = int | 1 | | unsigned long (int) | 4 bytes | = unsigned int | 1 | | long long (int) | 8 bytes | -9.22337E+18 to 9.22337E+18 | 1 | | unsigned long long (int) | 8 bytes | 0 to 1.84467E+19 | 1 | | | | | | | enum | 4 bytes | = int | 1 | | | | | | | float | 4 bytes | 3.4E-38 to 3.4E+38 | 6 digits | | double | 8 bytes | 1.7E-308 to 1.7E+308 | 15 digits | | long double | 10 bytes | 1.2E-4932 to 1.2E+4932 | 18 digits |