Lua 'end' expected to close 'if' - if-statement

I have this code here in lua
function onMouseDown(event)
print(event.x, event.y)
if event.x>160 then
print("what")
return 1
print("whatwhat")
else
return 0
print("WhatWhatWhat")
end
fruit:setX(event.x)
fruit:setY(event.y)
end
But it is moaning that main.lua:59: 'end' expected (to close 'if' at line 56) near 'print' so it is expecting an end at the end of my if below print("whatwhat").
But I put an end there and it still moans at me if I do that.
I am pretty new to lua and I am a bit confused, I normally program in c#

See the Lua manual §3.3.4:
The return statement can only be written as the last statement of a block. If it is really necessary to return in the middle of a block, then an explicit inner block can be used, as in the idiom do return end, because now return is the last statement in its (inner) block.
Your code has calls to print that occur after the return statement, and so is invalid.

I suspect your problem is the print after the return. That's dead code; Lua wants returns at the end of a block.

Related

Error return, gotos and code duplication in modern Fortran

In legacy Fortran code it's relative common to find this kind construct:
irc=0
...
if (foo) goto 10
...
if (bar) goto 10
...
return
10 irc=1
return
i.e., the irc variable holds the return code, and whenever an error occurs, a simple goto 10 accomplishes both setting a value and returning from the subroutine.
In modern code, where one tries to avoid gotos at all cost (https://xkcd.com/292/), what would be the best way to rewrite this? The trivial inlining causes a lot of code duplication and alternate returns (which look almost as bad as gotos):
irc=0
...
if (foo) then
irc=1
return
end if
...
if (bar) then
irc=1
return
end if
...
return
To avoid code duplication one could use an internal subroutine (especially if there are several statements to repeat every time), but that still leaves the returns. Or is there some way to force a return on the host subroutine from the internal one? Any other solution?
It is not possible for a procedure to complete execution of a distinct procedure (except through program termination). That is, an internal procedure's RETURN statement can't be used to manage the desired flow.
However, the desired flow here can be managed with a BLOCK construct such as in the following way:
main_flow: block
irc=0
...
if (foo) exit main_flow
...
if (bar) exit main_flow
...
return
end block main_flow
...
Clearly the conditions and actions can be more involved, and there can be a test outside the block if one is averse to returning from middles of procedures.
The block construct is such that an EXIT from within acts like a GO TO to the end of the block.
DO constructs with a single iteration count can also act in this way.

C++ - returning 0

So I'm completely new to C++ but know already a lot about Java.
I'm currently watching thenewboston's tutorial and he said that if you return 0 the computer knows the program works successfully.
Well, my question is now: Does this affect functions? If I want to return a calculated number and it's surprisingly 0, do I get 0 back or does the function send nothing back?
you return 0 the computer knows the program works successfully.
This is specific to the main function. Any other function can return whatever they want. Main is special in that it is the entry point for your program and also the exit point. When your program starts main is called when it only ends once main returns. Watching the return code of the main function is I think a practice that is going out of style these days but you still see a lot of code returning things like -1 when an error occurs. Who's watching that error code? The OS most of the time.
Returning zero is a convention, especially in Unix world. If a program (so it's main() function) returns zero, it means it finished successfully. Other values can (not neccesarily though) mean an error. You can see sysexits.h for a list of common return codes.
Also, if you miss return statement, main() will still (implicitly) return zero (valid for C++). It is defined in C++ standard, 3.6.1 point 5:
If control reaches the end of main without encountering a return
statement, the effect is that of executing return 0;
In shell, ex. Bash, you can check what value has been returned from main() by looking at $? variable, on example:
$ g++ prog.cpp
$ ./a.out
$ echo $?
0
For functions other than main() you should remember that zero, in comparison, is a boolean false, so returning zero may not be intepreted as a success (or true). But the return value can be anything and, in general, it does not have any special meaning, so returning zero is okay.
Returning 0 in the main function is the only one that has any special meaning. It's generally so that the OS can understand the program was successful, it's not particularly interesting insofar as C++ internals itself.

Do you need to break after you return false

In a switch statement inside a bool function I have this. Do I add break or is it implied I am very bad at this.
case Stop:
default:
return false;
//break;??????
No if you return from default case break statement isn't necessary there.
You must add break statement only after all your cases which you want to operate and stop switch's work, otherwise default is operated returning from function.
No break is required as return will be the last statement executed in the function.
It is not "implied", but since the code will never get there, you don't have to write break;.
It's just redundant, return is enough.
program execution will never reach at the break statement if it has return statement before it.
After return the program will not reach the break so you can remove the statement from there.

Warning message purpose?

While compiling a while loop without a body, I saw this message:
warning: suggest a space before ';' or explicit braces around empty body in
'while' statement
Why should I put a space? Is it to make it clearer that my loop isn't really doing anything?
Yes -- the usual convention is to put it on a line by itself, something like this:
while (*d++ = *s++)
;
A few people prefer to use things like:
while (*d++ = *s++)
{
/* intentionally empty */
}
Why should I put a space? Is it to make it clearer that my loop isn't really doing anything?
Yes, exactly that.
Many inexperienced programmers often put the ; after a control flow statement like for or while because they assume that ; goes at the end of every line, and not just at the end of statements and declarations. The warning is just suggesting to make it clearer that you understand that you've created an empty loop.
A more obvious empty-body loop syntax is to use the continue statement:
while (condition_with_side_effects)
continue;
That way no one will think you've accidentally added an extraneous ;:
while (condition); // bad style
Yes, it is just to show that you have not automatically placed a semicolon at the end of the line by mistake.

WARNING Control reaches end of non-void function c++

I have following function in C++ code (Its just an example)
Object& XYZ::getObject(InObj obj) {
try{
return obj.getObj();
}
DC_THROW_ERROR(ExceptionObj, "Object Not Found"); // Macro which throws an exception
}
When I compile the above code I get Warning (ie control reaches end of non-void function)..The Macro gets expanded before compilation. So the compiler is aware that if its not returning something its throwing an exception. If so why does compiler gives warning?? These type of functions are evrywhere in my project. To get rid of these warnings i have written below line after the Macro.
return *(static_cast<Object*>(0));
Is it a correct way of fixing it?? I know its bit dodgy.. I can't change the code as for that i have to change around 1000 functions. So can anyone please tell me if there is any better way of fixing it??
Thanks
Listen to the compiler. Get rid of the (so far undisclosed) macro. Or just fix it, but better get rid of it -- you're into the make-C++-look-like-language-X thing, which is ungood.
Cheers & hth.,
Assuming the code in the question is a faithful representation of the code that is causing the problem, the macro DC_THROW_ERROR must be something like
#define DC_THROW_ERROR(err) catch(...) {throw err;}
That semicolon after the DC_THROW_ERROR("Object Not Found") thus results in
Object& XYZ::getObject(InObj obj) {
try {
return obj.getObj();
}
// This is the expansion of DC_THROW_ERROR("Object Not Found")
catch (...) {
throw ("Object Not Found");
}
; // This is the semicolon that follows DC_THROW_ERROR("Object Not Found")
}
It is that extraneous semicolon, not the macro, that is getting the compiler in a tizzy about control reaching the end of a non-void function. That said, since statements in C and C++ are supposed to end with a semicolon, it is only natural that the human author of the code will add a semicolon after the end of the macro invocation.
Do you really need a macro here? Macros are evil in general. This macro is evil incarnate.
It makes that try-catch block look like invalid syntax. Macros that make the code look invalid are doubly evil.
It renames syntax. Doing #define BEGIN { is evil. Macros that rename syntax are doubly evil.
It invites the programmer to add that semicolon at the end. Macros that should not be followed with a semicolon are doubly evil.
That the macro invocation should not be followed with a semicolon apparently is not documented. Macros that do something evil but don't document the evilness are doubly evil.
All told, this macro is 2x2x2x2, or sixteen-fold evil. That makes this devil code.