"invalid controlling predicate" compiler error using OpenMP - c

I'm creating a basic prime number checker, based on C - determine if a number is prime , but utilising OpenMP.
int isPrime(int value)
{
omp_set_num_threads(4);
#pragma omp parallel for
for( int j = 2; j * j <= value; j++)
{
if ( value % j == 0) return 0;
}
return value;
}
When compiling with -fopenmp, GCC version 4.7.2 is erroring, stating invalid controlling predicate with respect to the for loop.
It looks like this error is caused by the j squared in the for loop. Is there a way I can work around this and still achieve the desired output from the algorithm?

return is not allowed inside the loop as it will cause exit before the curly braces.
Note the definition given below :
From the OpenMP V2.5 spec, 1.2.2 OpenMP language terminology, p2:17-
structured block - For C/C++, an executable statement, possibly
compound, with a single entry at the top and a single exit at the
bottom.
A structured block starts with the open { and ends with the closing }. The return is contained within these braces, so this program also violates the OpenMP definition for a structured block, because it has two exits (one at the return and one at the exit through the brace)
OpenMP places the following five restrictions on which loops can be threaded:
The loop variable must be of type signed integer. Unsigned integers,
such as DWORD's, will not work.
The comparison operation must be in the form loop_variable <, <=, >,
or >= loop_invariant_integer
The third expression or increment portion of the for loop must be
either integer addition or integer subtraction and by a loop
invariant value.
If the comparison operation is < or <=, the loop variable must
increment on every iteration, and conversely, if the comparison
operation is > or >=, the loop variable must decrement on every
iteration.
The loop must be a basic block, meaning no jumps from the inside of
the loop to the outside are permitted with the exception of the exit
statement, which terminates the whole application. If the statements
goto or break are used, they must jump within the loop, not outside
it. The same goes for exception handling; exceptions must be caught
within the loop.

According to the OpenMP standard (§2.5.1, p.40), the acceptable forms of the controlling predicate of the for loop are:
var relational-op b, and
b relational-op var
Your use of j * j <= value is a clear violation of this requirement. The rationale is that it requires the compiler to emit code that computes the integer square root of value at run time, with the latter being undefined for some values of value, specifically for the negative ones.
You can replace j * j <= value with j <= sqrt_value, where sqrt_value is the integer square root of value, but then would come the problem with having an alternative exit path in the structured block inside the loop. Unfortunately no easy solution exists in this case since OpenMP does not support premature termination of parallel loops.

Related

Can someone explain how this works? [duplicate]

I saw this code:
if (cond) {
perror("an error occurred"), exit(1);
}
Why would you do that? Why not just:
if (cond) {
perror("an error occurred");
exit(1);
}
In your example it serves no reason at all. It is on occasion useful when written as
if(cond)
perror("an error occured"), exit(1) ;
-- then you don't need curly braces. But it's an invitation to disaster.
The comma operator is to put two or more expressions in a position where the reference only allows one. In your case, there is no need to use it; in other cases, such as in a while loop, it may be useful:
while (a = b, c < d)
...
where the actual "evaluation" of the while loop is governed solely on the last expression.
Legitimate cases of the comma operator are rare, but they do exist. One example is when you want to have something happen inside of a conditional evaluation. For instance:
std::wstring example;
auto it = example.begin();
while (it = std::find(it, example.end(), L'\\'), it != example.end())
{
// Do something to each backslash in `example`
}
It can also be used in places where you can only place a single expression, but want two things to happen. For instance, the following loop increments x and decrements y in the for loop's third component:
int x = 0;
int y = some_number;
for(; x < y; ++x, --y)
{
// Do something which uses a converging x and y
}
Don't go looking for uses of it, but if it is appropriate, don't be afraid to use it, and don't be thrown for a loop if you see someone else using it. If you have two things which have no reason not to be separate statements, make them separate statements instead of using the comma operator.
The main use of the comma operator is obfuscation; it permits doing two
things where the reader only expects one. One of the most frequent
uses—adding side effects to a condition, falls under this
category. There are a few cases which might be considered valid,
however:
The one which was used to present it in K&R: incrementing two
variables in a for loop. In modern code, this might occur in a
function like std::transform, or std::copy, where an output iterator
is incremented symultaneously with the input iterator. (More often, of
course, these functions will contain a while loop, with the
incrementations in separate statements at the end of the loop. In such
cases, there's no point in using a comma rather than two statements.)
Another case which comes to mind is data validation of input parameters
in an initializer list:
MyClass::MyClass( T const& param )
: member( (validate( param ), param) )
{
}
(This assumes that validate( param ) will throw an exception if
something is wrong.) This use isn't particularly attractive, especially
as it needs the extra parentheses, but there aren't many alternatives.
Finally, I've sometimes seen the convention:
ScopedLock( myMutex ), protectedFunction();
, which avoids having to invent a name for the ScopedLock. To tell
the truth, I don't like it, but I have seen it used, and the alternative
of adding extra braces to ensure that the ScopedLock is immediately
destructed isn't very pretty either.
This can be better understood by taking some examples:
First:
Consider an expression:
x = ++j;
But for time being, if we need to assign a temporarily debug value, then we can write.
x = DEBUG_VALUE, ++j;
Second:
Comma , operators are frequently used in for() -loop e.g.:
for(i = 0, j = 10; i < N; j--, i++)
// ^ ^ here we can't use ;
Third:
One more example(actually one may find doing this interesting):
if (x = 16 / 4), if remainder is zero then print x = x - 1;
if (x = 16 / 5), if remainder is zero then print x = x + 1;
It can also be done in a single step;
if(x = n / d, n % d) // == x = n / d; if(n % d)
printf("Remainder not zero, x + 1 = %d", (x + 1));
else
printf("Remainder is zero, x - 1 = %d", (x - 1));
PS: It may also be interesting to know that sometimes it is disastrous to use , operator. For example in the question Strtok usage, code not working, by mistake, OP forgot to write name of the function and instead of writing tokens = strtok(NULL, ",'");, he wrote tokens = (NULL, ",'"); and he was not getting compilation error --but its a valid expression that tokens = ",'"; caused an infinite loop in his program.
The comma operator allows grouping expression where one is expected.
For example it can be useful in some case :
// In a loop
while ( a--, a < d ) ...
But in you case there is no reason to use it. It will be confusing... that's it...
In your case, it is just to avoid curly braces :
if(cond)
perror("an error occurred"), exit(1);
// =>
if (cond)
{
perror("an error occurred");
exit(1);
}
A link to a comma operator documentation.
There appear to be few practical uses of operator,().
Bjarne Stroustrup, The Design and Evolution of C++
Most of the oft usage of comma can be found out in the wikipedia article Comma_operator#Uses.
One interesting usage I have found out when using the boost::assign, where it had judiciously overloaded the operator to make it behave as a comma separated list of values which can be pushed to the end of a vector object
#include <boost/assign/std/vector.hpp> // for 'operator+=()'
using namespace std;
using namespace boost::assign; // bring 'operator+=()' into scope
{
vector<int> values;
values += 1,2,3,4,5,6,7,8,9; // insert values at the end of the container
}
Unfortunately, the above usage which was popular for prototyping would now look archaic once compilers start supporting Uniform Initialization
So that leaves us back to
There appear to be few practical uses of operator,().
Bjarne Stroustrup, The Design and Evolution of C++
In your case, the comma operator is useless since it could have been used to avoid curly braces, but it's not the case since the writer has already put them. Therefore it's useless and may be confusing.
It could be useful for the itinerary operator if you want to execute two or more instructions when the condition is true or false. but keep in mind that the return value will be the most right expression due to the comma operator left to right evalutaion rule (I mean inside the parentheses)
For instance:
a<b?(x=5,b=6,d=i):exit(1);
The boost::assign overloads the comma operator heavily to achieve this kind of syntax:
vector<int> v;
v += 1,2,3,4,5,6,7,8,9;

Figuring out what this function does?

I have to rewrite this for loop into a do while loop, but I can't figure out what this does. Please help
for(;; done = (int) sum == 5
{if (done) break;
sum += 2.6;}
Let's assume that the syntax error is resolved, so that the code reads
for(;; done = (int) sum == 5)
{
if (done) break;
sum += 2.6;
}
Now this code works as follows: the for loop has no initialization expression and no test expression, so it begins execution unconditionally. The first thing that happens is the "flag" done (an undefined object that I'm assuming is an int that may or may not be initialized to zero) is checked. If it's true (non-zero), the code breaks out of the for loop. if not, 2.6 (a double) is added to sum (an undefined object that I'm assuming is a double and that may or may not be initialized to a sensible value, or a number at all). When execution reaches the closing brace, the iteration statement in the for loop is executed, which compares sum to 5 (after converting sum to an integer value), and assigns the result of the comparison (i.e. 1 for true and 0 for false) to done.
Converting this to a while loop ought to be fairly straightforward. Simply execute these steps in order. Note that since the first piece of code to execute is checking if(done), the code more naturally lends itself to a simple while than a do-while loop.
Note that this would have been considerably clearer if you had defined the types of your variables, and provided initial values for them.

For versus while versus do loop statements

Is there a difference between for and while statements? Is it just syntax?
#include <stdio.h>
void main() {
int cent_temp = 0;
int fah_temp;
while (cent_temp <= 20) {
fah_temp = (9 * cent_temp) / 5 + 32;
printf("%d degrees C = %d degrees F\n", cent_temp, fah_temp);
cent_temp++;
}
}
This means to me....
While the value of cent_temp is less than 20 then calculate fah_temp. Then increase the value of cent_temp by 1 and check it is still less than 20; then go round the loop again.
Regarding the syntax:
printf("%d degrees C = %d degrees F\n", cent_temp, fah_temp);
This means %d means print to the screen, replace with a decimal number the value of cent_temp and %d means replace with a decimal number the value of fah_temp.
#include <stdio.h>
void main() {
int cent_temp;
int fah_temp;
for (cent_temp = 0; cent_temp <= 20; cent_temp++) {
fah_temp = (9 * cent_temp) / 5 + 32;
printf("%2d degrees C = %2d degrees F\n", cent_temp, fah_temp);
}
}
My interpretation of the above is:
for cent_temp = 0 repeat while cent_temp less than 20 and then execute cent_temp+1 at the end. So cent_temp 0 goes into the loop to calculate fah_temp and gets printed to the screen. Then cent_temp goes up by one then goes round the loop again. Here I've used %2d instead of %d to signify that it should have 2 spaces for a decimal number (and they line up when executed). Both codes will not execute if cent_temp > 20.
Similarly rearranging the statement in a do while loop has a similar effect and doesn't really have an impact on the result.
Does each type of loop have a different application?
Please correct me if I wrong!
Is there a difference between 'for' and 'while' statements? Is it just
syntax?
To me, it is just syntax.
From K&R section 3.5 Loops -- While and For, I quote:
The for statement
for (expr1; expr2; expr3)
statement
is equivalent to
expr1;
while (expr2) {
statement
expr3;
}
except for the behavior of continue.
Grammatically, the three components of a for loop are expressions.
Most commonly, expr1 and expr3 are assignments or function calls
and expr2 is a relational expression.
Notes
As user #chqrlie has mentioned in the comments, control statements like break and continue make the situation slightly murkier.
There are some situations where the modify statement is necessary in the loop body. For example Erase-remove idiom with std::set failing with constness-related error (in C++ though)
Example
As an example, let us write a loop to print all the odd numbers between 1 and 100.
int i = 1;
while (i <= 100) {
printf("%d\n", i);
i += 2;
}
for (int i = 1; i <= 100; i += 2) {
printf("%d\n", i);
}
Opinion
I am not a language expert, but in most situations in practice I find them transformable.
I personally prefer using for syntax because:
loop control structure is in one single place (the for header) making it easy to read, and
the loop variable (e.g. i) is not exposed to the outer scope.
for(cent_temp = 0; cent_temp <= 20; cent_temp++)
{ /* code */ }
is 100% equivalent to
cent_temp = 0;
while(cent_temp <= 20)
{
/* code */
cent_temp++;
}
But a do-while is different since it puts the condition check at the end.
As for when to use which loop, it is a matter of style and therefore a bit subjective. The industry de facto standard style, used by the majority of all C programmers, goes like this:
for loops should always be used when performing a known number of iterations. It is then considered the most readable form.
while loops should be used the the number of iterations is unknown in advance, or when the loop is turning complex for some reason. For example if you need to alter the loop iterator variable inside the loop body, then you should use a while loop instead of a for loop.
do while loops should be used for special cases where you need to skip the condition check the first lap of the loop, for example do { result = send(); } while(result == ok);.
I looked at my Code Complete by Steve McConnell (the bible).
Here is what you can read in chapter 16:
A for loop is a good choice when you need a loop that executes a specified number of times. [...]
Use for loops for simple activities that don't require internal loops controls. Use them when the loop involves simple increments or simple decrements, such as iterating through the elements in a container. The point of a for loop is that you set it up at the top of the loop and then forget about it. You don't have to do anything inside the loop to control it. If you have a condition under which execution has to jump out of a loop, use a while loop instead.
Likewise, don't explicitly change the index value of a for loop to force it to terminate. Use a while loop instead. The for loop is for simple uses. Most complicated looping tasks are better handled by a while loop.
In general, you would use a for loop to iterate over a finite set of values, whereas you'd use a while or do-while loop to iterate while a specific condition or set of conditions is true. In most of C's contemporaries (Basic, Pascal, Fortran, etc.), a for loop can only iterate over a scalar index:
Fortran:
DO 10 i=1,10
statements
10 CONTINUE
Pascal:
for i := 1 to 10 do
begin
statements
end;
Both of these snippets loop exactly 10 times. The index i is initialized and updated by the loop automagically. I'd have to go back and check, but I'm pretty sure you cannot write to i in the loop body.
C actually blurred the lines between a for and while loop by adding the control expression:
for ( init-expr ; control-expr ; update-expr )
statement
In C, a for loop can iterate over a scalar just like Fortran or Pascal:
for( i = 0; i < 10; i++ )
{
do_something_with( i );
}
Or it can iterate over multiple scalars:
for ( i = 0, j = 0; i < 10 && j < 10; i++, j++ )
{
do_something_with( i, j );
}
Or it can iterate over the contents of a file:
for( c = fgetc( in ); c != EOF; c = fgetc( in ) )
{
do_something_with( c );
}
Or it can iterate over a linked list:
for( cur = head; cur != NULL; cur = cur->next )
{
do_something_with( cur );
}
In Fortran and Pascal, those last three loops would have to be expressed as while loops (which I'm not going to do, because I've pretty much exhausted my Fortran and Pascal knowledge already).
The other big difference between a C for loop and those of Fortran or Pascal is that you can write to the loop index (i, j, c, or cur) in the loop body; it's not specially protected in any way.
A while or do-while loop is used to iterate as long as a specific condition or set of conditions is true:
while( control-expr )
statement
do
statement
while( control-expr );
In both a for and while loop, the condition is tested before the loop body executes; in a do-while loop, the condition is tested after the loop body executes, so a do-while loop will always execute at least once.
In C, you can use either a for loop or a while loop in many circumstances:
while ( ( c = fgetc( in ) ) != EOF )
do_something_with( c );
for ( c = fgetc( in ); c != EOF; c = fgetc( in ) )
do_something_with( c );
Both loops do exactly the same thing; it's just a matter of which one you think more clearly expresses your intent, or which you think would be easier for other people to understand.
From the point of view of algorithmic for and while are not the same. Shortly, in algorithmic, for should be used when bounds are known and while when you don't know if the condition can be met or when it can be. For is to repeat something n times (n known), which is exactly the case of your example computation; a for loop should be used (don't you think what the loop makes is more clearly stated in the for loop ?). If you want an example of a must be used while loop, look at something like Collatz sequence. From a point of view of computability, for loops can always be transformed in while loops but not the converse.
From the point of view of computer languages it is now common to fuse both, in C for example, it makes no difference, only syntactic. But remember that in some other language that could be very different, for example in Pascal for loops are very limited.
Source code is written not only to be compiled and executed by computers but also to be read and understood by humans.
A computer doesn't really mind whether a for loop, a while loop or a goto is used. On the other hand, a human expects different meanings for different structures.
computing values over a known range of inputs is best shown with a for loop;
reading a file up to its end is best shown with a while loop.
Choosing which structure to use is similar as choosing a variable name.

Is array value as loop stop condition read every time?

Example:
for (int i = 0; i < a[index]; i++) {
// do stuff
}
Would a[index] be read every time? If no, what if someone wanted to change the value at a[index] in the loop? I've never seen it myself, but does the compiler make such an assumption?
If the condition was instead i < val-2, would it be evaluated every time?
The compiler will perform optimizations normally when the system is not impacted by other parts of the program. So if you make changes inside the for loop on the condition parameter, the compiler will not optimize.
As mentioned, the compiler should read the array and check it before each iteration in your code snippet. You can optimize your code as follows, then it will read the array only once for loop condition checking.
int cond = a[index];
for (int i = 0; i < cond; i++) {
// do stuff
}
well, maybe.
A standards compliant compiler will produce code that behaves as-if it
is read every time.
If index and/or array are of storage class volatile the they will be re-evaluated every time.
If they are not and the loops content doesn't use them in a way that can be expected to modify their value the optimiser may decide to use a cached result instead.
Co does not store results of expressions in temporary variables. So, all expressions re evaluated in-place. Note that any for loop can be changed to a while loop:
for ( def_or_expr1 ; expr2 ; expr3 ) {
...
}
becomes:
def_or_expr1;
while ( expr2 ) {
...
cont:
expr3;
}
Update: continue in the for loop would be the same as goto cont; int the while loop above. I.e. expr3 is evaluated for every iteration.
The compiler can bascially apply any optimization it can proof not to change the program's essence. Describing full details would be too far for this, but in general, it can (and will) optimize:
a[index] is not changed in the loop: read once before loop and keep in a temp (e.g. register).
a[index] is changed in the loop: update the temp (register) with the new value, avoiding memory access (and the index calculations).
For this, the compiler must assume the array is not changed outside the visible control flow. This is typically the file being compiled (with all included files). For modern systems using link time optimization (LTO), this can be the whole final program - minus dynamic libraries.
Note this is a very brief description. Actually, the C standard defines pretty clear how a program has to be executed, so what/how the compiler may optimize.
If the array is changed, for example by an interrupt handler or another thread, things become complicated. Depending on your target, you need from volatile, atomic operations (stdatomic.h, since C11) up to thread locks/mutexes/semapores/etc. to control accesses to the share resource.

What is the full "for" loop syntax in C?

I have seen some very weird for loops when reading other people's code. I have been trying to search for a full syntax explanation for the for loop in C but it is very hard because the word "for" appears in unrelated sentences making the search almost impossible to Google effectively.
This question came to my mind after reading this thread which made me curious again.
The for here:
for(p=0;p+=(a&1)*b,a!=1;a>>=1,b<<=1);
In the middle condition there is a comma separating the two pieces of code, what does this comma do? The comma on the right side I understand as it makes both a>>=1 and b<<=1.
But within a loop exit condition, what happens? Does it exit when p==0, when a==1 or when both happen?
It would be great if anyone could help me understand this and maybe point me in the direction of a full for loop syntax description.
The comma is not exclusive of for loops; it is the comma operator.
x = (a, b);
will do first a, then b, then set x to the value of b.
The for syntax is:
for (init; condition; increment)
...
Which is somewhat (ignoring continue and break for now) equivalent to:
init;
while (condition) {
...
increment;
}
So your for loop example is (again ignoring continue and break) equivalent to
p=0;
while (p+=(a&1)*b,a!=1) {
...
a>>=1,b<<=1;
}
Which acts as if it were (again ignoring continue and break):
p=0;
while (true) {
p+=(a&1)*b;
if (a == 1) break;
...
a>>=1;
b<<=1;
}
Two extra details of the for loop which were not in the simplified conversion to a while loop above:
If the condition is omitted, it is always true (resulting in an infinite loop unless a break, goto, or something else breaks the loop).
A continue acts as if it were a goto to a label just before the increment, unlike a continue in the while loop which would skip the increment.
Also, an important detail about the comma operator: it is a sequence point, like && and || (which is why I can split it in separate statements and keep its meaning intact).
Changes in C99
The C99 standard introduces a couple of nuances not mentioned earlier in this explanation (which is very good for C89/C90).
First, all loops are blocks in their own right. Effectively,
for (...) { ... }
is itself wrapped in a pair of braces
{
for (...) { ... }
}
The standard sayeth:
ISO/IEC 9899:1999 §6.8.5 Iteration statements
¶5 An iteration statement is a block whose scope is a strict subset of the scope of its
enclosing block. The loop body is also a block whose scope is a strict subset of the scope
of the iteration statement.
This is also described in the Rationale in terms of the extra set of braces.
Secondly, the init portion in C99 can be a (single) declaration, as in
for (int i = 0; i < sizeof(something); i++) { ... }
Now the 'block wrapped around the loop' comes into its own; it explains why the variable i cannot be accessed outside the loop. You can declare more than one variable, but they must all be of the same type:
for (int i = 0, j = sizeof(something); i < j; i++, j--) { ... }
The standard sayeth:
ISO/IEC 9899:1999 §6.8.5.3 The for statement
The statement
for ( clause-1 ; expression-2 ; expression-3 ) statement
behaves as follows: The expression expression-2 is the controlling expression that is
evaluated before each execution of the loop body. The expression expression-3 is
evaluated as a void expression after each execution of the loop body. If clause-1 is a
declaration, the scope of any variables it declares is the remainder of the declaration and
the entire loop, including the other two expressions; it is reached in the order of execution
before the first evaluation of the controlling expression. If clause-1 is an expression, it is
evaluated as a void expression before the first evaluation of the controlling expression.133)
Both clause-1 and expression-3 can be omitted. An omitted expression-2 is replaced by a
nonzero constant.
133) Thus, clause-1 specifies initialization for the loop, possibly declaring one or more variables for use in
the loop; the controlling expression, expression-2, specifies an evaluation made before each iteration,
such that execution of the loop continues until the expression compares equal to 0; and expression-3
specifies an operation (such as incrementing) that is performed after each iteration.
The comma simply separates two expressions and is valid anywhere in C where a normal expression is allowed. These are executed in order from left to right. The value of the rightmost expression is the value of the overall expression.
for loops consist of three parts, any of which may also be empty; one (the first) is executed at the beginning, and one (the third) at the end of each iteration. These parts usually initialize and increment a counter, respectively; but they may do anything.
The second part is a test that is executed at the beginning of each execution. If the test yields false, the loop is aborted. That's all there is to it.
The C style for loop consists of three expressions:
for (initializer; condition; counter) statement_or_statement_block;
The initializer runs once, when the loop starts.
The condition is checked before each iteration. The loop runs as long it evaluates to true.
The counter runs once after each iteration.
Each of these parts can be an expression valid in the language you write the loop in. That means they can be used more creatively. Anything you want to do beforehand can go into the initializer, anything you want to do in between can go into the condition or the counter, up to the point where the loop has no body anymore.
To achieve that, the comma operator comes in very handy. It allows you to chain expressions together to form a single new expression. Most of the time it is used that way in a for loop, the other implications of the comma operator (e.g. value assignment considerations) play a minor role.
Even though you can do clever things by using syntax creatively - I would stay clear of it until I find a really good reason to do so. Playing code golf with for loops makes code harder to read and understand (and maintain).
The wikipedia has a nice article on the for loop as well.
Everything is optional in a for loop. We can initialize more than one variable, we can check for more than one condition, we can iterate more than one variable using the comma operator.
The following for loop will take you into an infinite loop. Be careful by checking the condition.
for(;;)
Konrad mentioned the key point that I'd like to repeat: The value of the rightmost expression is the value of the overall expression.
A Gnu compiler stated this warning when I put two tests in the "condition" section of the for loop
warning: left-hand operand of comma expression has no effect
What I really intended for the "condition" was two tests with an "&&" between. Per Konrad's statement, only the test on to the right of the comma would affect the condition.
Formal syntax of the for loop:
for (init-statement condition; iteration-expression)
statement
Corresponding flowchart:
Equivalent program:
{
init-statement
while (condition) {
statement
iteration-expression;
}
}
Except that
Names declared by init-statement (if init-statement is a declaration) and names declared by condition (if condition is a declaration) are in the same scope (which is also the scope of statement).
continue in statement will execute iteration-expression.
Empty condition is equivalent to while (true).
the for loop is execution for particular time for(;;)
the syntex for for loop
for(;;)
OR
for (initializer; condition; counter)
e.g (rmv=1;rmv<=15;rmv++)
execution to 15 times in for block
1.first initializ the value because start the value
(e.g)rmv=1 or rmv=2
2.second statement is test the condition is true or false ,the condition true no.of time execution the for loop and the condition is false terminate for block,
e.g i=5;i<=10 the condition is true
i=10;i<10 the condition is false terminate for block,
3.third is increment or decrement
(e.g)rmv++ or ++rmv

Resources