Use of undeclared identifier

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 );
}

Please help

Very strange. How do you run this code in cling?

It is a script. I just run the script ./script, even cling .x script yields same error

How do you get from script.cxx to ./script?

@cw2636 I cannot reproduce this:

> ./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?

OK found it:

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:

void mkDir ( string strDir ) {
  mode_t mode = 0777;

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 

@Axel This reminds me that I also often face this problem, usually when I “copy & paste” some piece of source code, e.g.:

for (int i = 0; i < 1; i++)
  cout << i << "\n";

So, could you please DISABLE this feature so that a trailing “;” is NOT added automatically?

Thanks. This was helpful

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.

Ideas?

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.

There is a nasty unsolved problem with “unnamed macros”, known since 11 years ago: “Return from an unnamed macro in ROOT 6 broken

Maybe when you finally fix this problem, also the artificial “;” will not be needed anymore.

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!

Still not clear what the connection between adding ; or not to function declarations and missing return for unnamed macros is.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.