Fortran line continuations with function or subroutine calls - fortran

I tried to continue a line with a call a function call using the & method, but I get an error that appears to be due to the compiler interpreting it as a parameter itself.
something = mrfuntion(parameter1, parameter2, parameter3 &
parameter4)
Is there a way to continue a line within a function call?

You are forgetting your comma. It should be
something = mrfuntion(parameter1, parameter2, parameter3, &
parameter4)

Related

Conditionally adding arguments to a constructor (C++)

Is there a way to conditionally add arguments to a constructor? I'd also like to know what this type of construction is called so I can search it myself.
I'm creating a boost::process::child using a constructor where I can pass any properties and things are mostly working great:
m_proc = new boost::process::child(
m_context,
boost::process::exe = m_config.exe,
boost::process::args = m_config.args,
boost::process::env = m_config.Environment,
boost::process::start_dir = m_config.WorkingDirectory,
boost::process::std_out > m_stdout_pipe,
boost::process::std_err > m_stderr_pipe,
boost::process::on_exit = [this](int i, auto e){OnProcExit(i, e);},
boost::process::extend::on_setup = [this](auto&){OnProcSetup();},
boost::process::extend::on_success = [this](auto&){OnProcSuccess();},
boost::process::extend::on_error = [this](auto&, auto ec){OnProcError(ec);}
);
UNTIL I call ls with no arguments. Then it returns
/usr/bin/ls: cannot access '': No such file or directory
Process Exited (code:2)
If m_config.args is empty, I want to avoid passing it. I tried:
m_proc = new boost::process::child(
...
boost::process::exe = m_config.exe,
m_config.args.empty() ? (void) : (boost::process::args = m_config.args),
...
);
but that gives:
error: expected primary-expression before ‘void’
I tried:
m_proc = new boost::process::child(
...
boost::process::exe = m_config.exe,
boost::process::args = m_config.args.empty() ? {} : m_config.args,
...
But that gives:
initializer list cannot be used on the right hand side of operator ?
error: expected primary-expression before ‘{’ token
I understand that for this particular case, I could combine exe and args to make a cmd, but I'd also like to conditionally add other arguments like boost::process::shell or boost::process::stdin.
If I need to call different constructor code for every set of options, I would need to write N! calls to constructors where N is the number of options and that grows fast.
This is ugly.
C++ isn't python, there isn't any named parameters in C++, so this solution makes use of global variables (boost::process::args) which are fundamentally not thread safe and prone to usage errors as you experienced.
In the boost documentation they state you don't need to use the global vars, so you can directly use the your config members here:
m_proc = new boost::process::child(
m_context,
m_config.exe,
m_config.args,
m_config.Environment,
[...]
By the way, the error you're reporting isn't due to a bad empty list passing (you can have m_config.args = {}) but probably to a wrong command argument list creation (if the list is empty, the boost::process::child code should create an non-empty string for the process's argument list, containing the executable name as the first argument).
The error you are reporting:
/usr/bin/ls: cannot access '': No such file or directory
is likely due to the wrong argument list being generated by boost and it's not due to your (empty) args array.
So I would put a debug breakpoint on the Popen syscall here and walk backward until I figure out what went wrong in building the argument string.
Using a global variable like a parameter here is syntax candy, but it means operator overloading to an unspecified object (as stated in the documentation), so you actually don't know what's going on here (a = b when a is unknown can be anything in C++, like a crazy making b set to the value of a as in T& operator =(T & b) { b = *this; return *this; }). You'll need to debug what's going on here to figure out what is happening. As a short advice, try to avoid using undefined object if it's not required and unclear, and stick to usual C++ practices.

Call of a function with String parameter direct vs variable

I ran into a problem I am not really understand developing a software on an ESP8266 using the ESP8266 core for Arduino. Basically my program crashes if I pass a String created at calling a function. I have a function with a String as parameter:
void SimpleFunc(String str)
{
...
}
I tried out two ways of calling this function with a very long String. First way is to create a new String variable and pass it:
String veryLongString = "veeeerryyyy loooong ........."; //Much longer in reality!!!
SimpleFunc(veryLongString);
Second way is to pass the String directly:
SimpleFunc("veeeerryyyy loooong .........");
Running the second sketch results in a crash. Here is a part of the stack:
umm_assimilate_up at ...\esp8266\2.3.0\cores\esp8266\umm_malloc/umm_malloc.c line 1163
String::~String() at ...\esp8266\2.3.0\cores\esp8266/WString.cpp line 720
_umm_free at ...\esp8266\2.3.0\cores\esp8266\umm_malloc/umm_malloc.c line 1287
free at ...\esp8266\2.3.0\cores\esp8266\umm_malloc/umm_malloc.c line 1733
String::~String() at ...\esp8266\2.3.0\cores\esp8266/WString.cpp line 720
Where is the difference in calling the function this ways? Why is the first approach working well and the second not?
If you call a string by reference
void foo(std::string const &str)
No copy of the underlying characters is made. If you call by value
void food(std::string str)
str is copied, which if it is very long is an expensive operation that could run the machine out of memory.

Using std transform on a C++ string

I am trying to get a bit of practice with std::transform by using it to decrypt a simple Caesar cypher. But apparentrly my function definition is wrong, since the compiler considers the unary function argument invalid. Here is my code:
char CryptoModule::UndoCaesar(char& letter)
{
return (letter - atoi(key_.c_str()) % 128);
}
void CryptoModule::DecryptCaesar()
{
std::transform(data_.begin(), data_.end(), data_.begin(), UndoCaesar);
}
Could anyone please tell me where the error lies ? In addition, what would I need to modify in order to use for_each ? I believe it would involve changing the return value to a void and storing the result in letter.
Thanks and have a nice day
Edit: Tried adding bind, but still not working. Current call is :
std::transform(data_.begin(), data_.end(), data_.begin(), bind(&UndoCaesar, this, std::placeholders::_1));
Your given member function has a hidden this parameter, so you need to bind that in order to pass it:
std::transform(data_.begin(), data_.end(), data_.begin(),
std::bind(&CryptoModule::UndoCaesar, this, std::placeholders::_1)
);
Note that std::bind is in <functional>. All this does is basically cause std::transform to call whatever function-like object, f, it takes like f(currentElement) and have that in turn call UndoCaesar(this, currentElement) with this being part of its state because you bound it.
Alternatively, you can wrap the call in a lambda that captures this so that it can be used for the member function call (implicitly, like normal):
std::transform(data_.begin(), data_.end(), data_.begin(),
[this](char c) {return UndoCaesar(c);}
);

CScope indexing with C++ and scoped function parameters

I'm using cscope to create an index of some C++ source code. Mostly it works great but it has problems when parsing function names that have parameter types that are scoped (using '::'). For example:
void SomeClass::doSomethingAwesome( const std::string& input )
{
}
When I use the cscope interface to "Find this C symbol:" I get this:
File Function Line
0 doSomethingAwesome <global> 1 void SomeClass::doSomethingAwesome( const std::string& input )
The important bit is the global tag. It should be 'doSomethingAwesome'.
For another function without any scoped parameters e.g.
void SomeClass::doSomethingElse( int input )
I get this:
File Function Line
0 doSomethingElse doSomethingElse 1 void SomeClass::doSomethingElse( int input )
Note the Function field now matches the function name. I can now successfully search in cscope for other functions that call this function. I could not do that with doSomethingAwesome(). In addition any functions which are only called from doSomethingAwesome() will not show up as having been called by any function since doSomethingAwesome() has not been recognised as a function by cscope.
Am I doing something wrong? Or is this an issue in cscope's parsing of the function?

Lua: getting global function failing after loading file

I'm attempting to call a function inside of a lua file called test2.lua
This is the contents of test2.lua:
function abc(path)
t = {}
table.insert(t, "a")
return t
end
As you can see it takes a single input and returns a string.
Here is my C code. It's pretty simple. However my call getglobal in order to call that function does not work... lua_getglobal says it isn't a function when I test it... Any reason why this is? Shouldn't abc be a global function returnable inside of the source file? Why then does it only find nil for this global?
L = lua_open();
luaL_openlibs(L);
luaL_loadfile(L, "src/test2.lua");
lua_getglobal(L, "abc");
lua_pushstring(L, "coollll");
int error = 0;
if ((error = lua_pcall(L, 1, 1, 0)) == 0)
{
std::cout << "cool";
}
EDIT:
calling lua_getglobal is causing my program to break control regardless of using loadfile or dofile... any idea why?
lua_getglobal crashing program
The function luaL_loadfile() reads, parses, and compiles the named Lua file. It does not execute any of its content. This is important in your case because the statement function abc(path)...end has no visible effect until it is executed. The function keyword as you've used it is equivalent to writing
abc = function(path)
t = {}
table.insert(t, "a")
return t
end
In this form, it is clearer that the variable named abc is not actually assigned a value until the code executes.
When luaL_loadfile() returns, it has pushed an anonymous function on the top of the Lua stack that is the result of compiling your file. You need to call it, and lua_pcall() will do the trick. Replace your reference to luaL_loadfile() with this:
if (luaL_loadfile(L, "src/test2.lua") || lua_pcall(L, 0, LUA_MULTRET, 0)) {
// do something with the error
}
At this point, test2.lua has been executed and any functions it defined or other global variables it modified are available.
This is a common enough idiom, that the function luaL_dofile() is provided to load and call a file by name.
There is a second, more subtle issue in your code as presented. The function abc() uses a variable named t, but you should be aware that t as used is a global variable. You probably meant to write local t = {} at the top of abc().
It's not enough to call luaL_loadfile: this puts a chunk onto the stack. Either follow up with luaL_[p]call to execute the chunk (thus making the function available), or use luaL_dofile.