After successful installing cling. I need to test the interpreter part of it. I create a simple script which is included at the end for some reason i am getting this error.
input_line_9:5:15: error: use of undeclared identifier ‘strDir’
if ( stat ( strDir.c_str ( ), &st ) == 0 )
^
input_line_9:7:11: error: use of undeclared identifier ‘strDir’
mkdir ( strDir.c_str ( ), mode );
^
input_line_11:4:4: error: use of undeclared identifier ‘mkDir’
mkDir(dir);
^
script.cxx:
#include <iostream>
#include <unistd.h>
#include <sys/stat.h>
#include <ctype.h>
using namespace std;
void mkDir ( string strDir )
{
mode_t mode = 0777;
struct stat st;
if ( stat ( strDir.c_str ( ), &st ) == 0 )
return; // directory exists.
mkdir ( strDir.c_str ( ), mode );
}
int main ( int argc, char *argv[] )
{
string dir = "/testing";
mkDir(dir);
std::cout << "Resetting remote " << std::endl;
exit ( 0 );
}
> ./inst/bin/cling ./script.cxx
warning: Failed to call `script()` to execute the macro.
Add this function or rename the macro. Falling back to `.L`.
is 100% of what is expected to happen. Most importantly there’s no syntax error here, loading that file works just fine. So - what are you doing differently?
cat script.cxx |./inst/bin/cling
****************** CLING ******************
* Type C++ code and press enter to run it *
* Type .q to exit *
*******************************************
input_line_9:5:15: error: use of undeclared identifier 'strDir'
if ( stat ( strDir.c_str ( ), &st ) == 0 )
^
input_line_9:7:11: error: use of undeclared identifier 'strDir'
mkdir ( strDir.c_str ( ), mode );
^
input_line_11:4:4: error: use of undeclared identifier 'mkDir'
mkDir(dir);
^
In this mode, each line is taken as separate input. cling sees void mkDir ( string strDir ) - and interprets this as a declaration where you left out the training ;. The next line { then just opens a scope - but not a function scope. I.e. you can think of cling interpreting you code as:
void mkDir ( string strDir );
{
mode_t mode = 0777;
struct stat st;
if ( stat ( strDir.c_str ( ), &st ) == 0 )
and now you see where the errors come from. The workaround is dead trivial: add the { after the function prototype, such that cling knows that input will continue:
Also note that main is not called by cling; for .x you can use a function with the same name as a file; for pasting lines into cling you need to invoke a function explicitly:
void someFunc() {
...
}
someFunc();
And then all of a sudden things work:
$ cat script.cxx |./inst/bin/cling
****************** CLING ******************
* Type C++ code and press enter to run it *
* Type .q to exit *
*******************************************
Resetting remote
We don’t do this for fun and profit but because of myFunc(x)+42 where people want to get the result printed. But it’s not valid C++, and to survive the liblang parsing we just always add a semicolon, unconditionally.
I predict we would also have tons of people complaining why they now have to add a ; after int x=42 but not after x=42 (which needs to print (int&) 42).
Maybe changing the parsing in cling - once we can reliably distinguish expressions from declarations before we add the training semicolon - could help, but I currently don’t see how to escape the user expectation outlined above.
In such cases, I can often help myself if I “encapsulate” the piece of source code in a “{ … }” pair (so, I create a tiny unnamed macro). Unfortunately, this often breaks, too.
Sorry Wile_E I have no idea what’s connecting these two problems? Could you explain / expand? Returns from unnamed macros vs what I explained above regarding int i = 42 vs i = 42 - what’s the connection? The fact that you enclose code in {} to hack around the declaration vs expression / continuation issue? Well, that’s just another workaround then, and int myfunc() { feels strictly superior as a workaround. Anyway I’d rather see us fix the underlying ; issue! But as I said: I need ideas how to maneuver user expectations - right now I don’t see how we could pull this off!