Unary operator following arithmetic operator (use parentheses) at (1) - fortran

When I am compiling a Fortran Code I am getting the following warning:
nse3dmpi_subs.f:603:15:
. -HALF*aimag(k3(k)*(uh(i,j,k,1)*conjg(uconv3h(i,j,k,1))-
1
Warning: Extension: Unary operator following arithmetic operator (use parentheses) at (1)
How do I get rid of the warning?

I got the exact same error recently. It happened because I ended one line with "+", did a line continuation, and started the next line with "-". I got rid of it by taking the "-" out of the second line and replacing the "+" with a "-". Instead of:
x = (really long expression) +
1 -2.*(other long expression)
I needed:
x = (really long expression) -
1 2.*(other long expression)
Alternatively, I could have done:
x = (really long expression) +
1 (-2.*(other long expression))

Related

Why do i get error when i use x+ but not when +x in this code?

x = 2
if x == 2:
print x
else:
x +
i get error like
print x +
^
SyntaxError: invalid syntax
+x calls __pos__(self) and is therefore a valid python statement; x + y is an expression that needs two operands (see binary arithmetic expressions); x + is invalid.
This is the unary operator +, which is like writing -x but doesn't really do anything. See this article for more information.
In +x, + is an operator that works on a single number, such as -x and ~x. You can refer the bottom table on https://docs.python.org/2/reference/expressions.html.
However, in x +, + is an operator for two numbers. In your code, the second number is not provided, so you got an error.
You can check this answer
What's the purpose of the + (pos) unary operator in Python? for why we need +x in Python.

Why isn't arr[-2] equivalent to -2[arr]?

#include <iostream>
using namespace std;
int main()
{
int arr[3] = { 10, 20, 30 };
cout << arr[-2] << endl;
cout << -2[arr] << endl;
return 0;
}
Output:
4196160
-30
Here arr[-2] is out of range and invalid, causing undefined behavior.
But -2[arr] evaluates to -30. Why?
Isn't arr[-2] equivalent to -2[arr]?
-2[arr] is parsed as -(2[arr]). In C (and in C++, ignoring overloading), the definition of X[Y] is *(X+Y) (see more discussion of this in this question), which means that 2[arr] is equal to arr[2].
The compiler parses this expression
-2
like
unary_minus decimal_integer_literal
That is definitions of integer literals do not include signs.
In turn the expression
2[arr]
is parsed by the compiler as a postfix expression.
Postfix expressions have higher precedence than unary expressions. Thus this expression
-2[arr]
is equivalent to
- ( 2[arr] )
So the unary minus is applied to the lvalue returned by the postfix expression 2[arr].
On the other hand if you wrote
int n = -2;
and then
n[arr]
then this expression would be equivalent to
arr[-2]
-2[arr] is equivalent to -(2[arr]), which is equivalent to -arr[2]. However, (-2)[arr] is equivalent to arr[-2].
This is because E1[E2] is identical to (*((E1)+(E2)))
The underlying problem is with operator precedence. In C++ the [], ie the Subscript operator hold more precedence (somewhat akin to preferance) than the - unary_minus operator.
So when one writes,
arr[-2]
The compiler first executes arr[] then - , but the unary_minus is enclosed within the bounds of the [-2] so the expression is decomposed together.
In the,
-2[arr]
The same thing happens but, the compiler executes 2[] first the n the - operator so it ends up being
-(2[arr]) not (-2)[arr]
Your understanding of the concept that,
arr[i] i[arr] and *(i+arr) are all the same is correct. They are all equivalent expressions.
If you want to write in that way, write it as (-2)[arr]. You will get the same value for sure.
Check this out for future referance :http://en.cppreference.com/w/cpp/language/operator_precedence

C++ CPPUNIT_ASSERT with two parameters

In some code i found the following line:
CPPUNIT_ASSERT(1, val.getBytefield().size());
Does this really compare the two parameters for equality? Normally, i would expect this comparison with CPPUNIT_ASSERT_EQUAL:
CPPUNIT_ASSERT_EQUAL(1, val.getBytefield().size());
The test compiles and the assertion works in case 1, but not in case 2. Where is the difference?
This just looks like broken code to me, probably the result of some refactoring or other editing that was done.
The CPPUNIT_ASSERT macro takes a single argument—a condition expression—and asserts that that condition is true (i.e., fails if it is false).
This code is attempting to pass two arguments, but rather than functioning as an argument delimiter here, the comma is actually working as the (somewhat obscure) comma operator. The comma operator evaluates its first operand, discards the result, and then evaluates to the result of the second operand. Therefore, the initial 1 is an irrelevant no-op. The code is equivalent to:
CPPUNIT_ASSERT(val.getBytefield().size());
which means that it's asserting that the byte field has a non-zero size.
Obviously, this is different from your second snippet of code:
CPPUNIT_ASSERT_EQUAL(1, val.getBytefield().size());
which asserts that the byte field's size is exactly equal to 1.
It seems like you are using a compiler has an extension, which accepts 2 parameters to a single argument macro. I guess it's MSVC, see this
Hence, the macro will check if the first argument is true or not, in your case, it's 1, which is contextual converted to the bool value true, by this expansion
#define CPPUNIT_ASSERT(C) \
( CPPUNIT_NS::Asserter::failIf( !(C), \
CPPUNIT_NS::Message( "assertion failed", \
"Expression: " #C), \
CPPUNIT_SOURCELINE() ) )
You can double check my statement by change:
CPPUNIT_ASSERT(1, val.getBytefield().size());
with:
CPPUNIT_ASSERT(1000, val.getBytefield().size());
CPPUNIT_ASSERT_EQUAL(1, val.getBytefield().size());
From my experiment, .size() will likely return a std::size_t. From the definition of CPPUNIT_ASSERT_EQUAL:
#define CPPUNIT_ASSERT_EQUAL(expected,actual) \
(assertEquals((expected), \
(actual), \
CPPUNIT_SOURCELINE(), \
"" ) )
and assertEquals:
template<class T>
void assertEquals ( const T & expected,
const T & actual,
SourceLine sourceLine,
const std::string & message
)
Because type of 1 (int) and return type of .size() (std::size_t) is different, then no matching function can be found, the compiler can not compile your code.
I think this is the solution:
CPPUNIT_ASSERT(1 == val.getBytefield().size());
CPPUNIT_ASSERT_EQUAL(std::size_t(1), val.getBytefield().size());

Ternary operator without the middle expression

I realized recently that you can use the ternary operator in GCC and clang without a middle (?: or ? : works) and it will insert the first expression into the middle:
// outputs 2
cout << (2 ?: 4);
// outputs 3
cout << (0 ? : 3);
Where is this in the standard? I looked and didn't see anything about it.
It isn't in the standard at all.
What you are observing is a GCC extension: https://gcc.gnu.org/onlinedocs/gcc/Conditionals.html
If you omit it, its value is taken from the first operand prior to contextual conversion to bool.
The extensions value lies in not repeating side-effects and reducing the source-codes size.

Error when passing negative integer to a function in OCaml

If I define a function in OCaml, for example let f x = x + 1;; and then I try to call it passing a negative number
f -1;; it gives to me the following error
Error: This expression has type int -> int
but an expression was expected of type int
Why this error occurs?
Basically, it comes from the precedence of the parser. The compiler believes that f -1 means you want to subtract f by 1. It has been complained about for ages now.
Typing in f (-1) or f ~-1 will solve your problem (the later using the "explicitly unary minus").
UPDATE:
As stated in the OCaml manual:
Unary negation. You can also write - e instead of ~- e.
Basically, - can be used both as a binary operator 4 - 1 and a unary operator -1. But, as in your case, there can be confusion: f - 1 is "f minus one" and not "f applied to minus one". So the ~- operator was added to have a non-confusing unary minus as well.
Note that the spaces are not significant here, and that won't change because a lot of already existing code may contain operations without space.