C++ or C Gotchas
Advices and Gotchas when using cling and jupyter¶
The cling and xeus docs are good, but some informations are missing : this notebook adds more details.
Cling official docs: https://root.cern.ch/cling
.x filename.cxx - loads filename and calls void filename() if defined
.L library | filename.cxx - loads library or filename.cxx
.printAST - shows the abstract syntax tree after each processed entity
.I path - adds an include path
xeus-cling official docs: https://xeus-cling.readthedocs.io/en/latest/index.html
Some gotchas with cling and jupyter¶
Do not define two functions in the same cell or a global variable with another function¶
Failure example¶
this cell will give an error : "function definition is not allowed here"
int foo() { return 42; } int foo2() {return 43; }
input_line_7:3:13: error: function definition is not allowed here
int foo2() {return 43; }
^
Interpreter Error:
Correction¶
Create two cells
int foo() { return 42; }
int foo2() {return 43; }
Add using namespace std¶
If you try to display a std::string or a std::vector
error: no template named 'basic_string'; did you mean 'std::basic_string'? You can solve this by adding a line using namespace std
Scanf does not work¶
scanf does not work properly. To make it work, we could write a wrapper around vsscanf. You could provide this code on top of the assignment as a read only code block for students. This should behave exactly like scanf but it uses std::cin internally .
#include <stdlib.h> #include<stdarg.h> #include <iostream> int scanf_lab(const char * str, ...) { std::string input_string; std::getline(std::cin, input_string); va_list args; va_start(args, str); int ret = vsscanf(input_string.c_str(), str, args ); va_end(args); return ret; } int n; scanf_lab("%d", &n);
11
n
11
Some more advices / missing docs¶
Add include path / And library path / load libraries¶
Add library and include path¶
#pragma cling add_library_path("...") will add a path to the library path
#pragma cling add_include_path("...") will add a path to the include path
Load libraries¶
#pragma cling load("mylibrary") will load a library. You do not need to add the library extension (.so, '.lib, or .dylib). You can also load a library using .L.
No semicolon in single line statements¶
Do not put a ";" at the end if you want to see the computation result The cell below will output a result:
2 * 3
6
2 * 3;
This is C++ : everything can be defined only once¶
If you run twice a code that defines the same variable or a function, you will encounter a compiler error, with a bad looking Red Error Message (error: redefinition of '...'). There are several ways to work around this but the easiest way is to select "Kernel/Restart" and re-run the different cells
Compiling header files and shared object files¶
Lets have a file a.cpp with some functions in the /root directory
int ret0 () { return 0; } int ret1() { return 1; }
Lets have a file a.h with some functions in the /root directory
int ret0 (); int ret1();
To compile shared object files, you have to install clang-9 and change paths.
apt install clang-9 export PATH=/usr/lib/llvm-9/bin/clang++:$PATH clang++ -shared a.cpp -o a.so
.L /root/a.so
#pragma cling add_include_path("/root/")
#include <a.h>
ret1()
1
ret0()
0