count_calls() function and the return value - c

im going through an old exam past paper and had this question
int c = 0;
int count_calls()
{
c = c + 1;
return c;
}
Now it asks why would this go wrong i.e. the number of calls counted is incorrect? is it right to say that no matter what c is set to in the count_calls() function it will always be zero due to the fact c is always defined as 0 outside the class? and would changing it to ++c or +CC fix this issue?

function increments global variable (and it will be correctly incremented by 1 every time the function was called), but when it returns, it creates local copy.
in the range of int type, it can count calls
generally speaking, it's bad code (it can't be used in parallel)
it wouldn't changed with moving to ++c

Related

In this function (in C) that takes an integer as an argument: Why isn't sum = 0 every time the function is called?

Update: Hi, I did not misunderstood the goal of the function. I was just surprised that static int sum = 0 does not execute each time the function is called, so I don't understand that. The goal of the function is correct: to sum the values and give the final value, and it works fine. The question is: Why isn't the sum changing into 0 each time the function is called? I suppose that's how it is set up by convention? That since I put static int sum, it will run only once and make it equal to zero, but then it won't run this line of the code again when the function is called?
In the following code, the only way I could make this function work was when I declared that sum = 0.
I was expecting the output to be 55, 45, 50, since sum is getting value 0 each time it is run! But for some reason, after the second time the function is called, the first line "static int sum = 0;" is skipped. Why? Thanks a lot =)
#include <stdio.h>
int sum (int num)
{
static int sum = 0;
sum = sum + num;
return sum;
}
int main()
{
printf("%d ",sum(55));
printf("%d ",sum(45));
printf("%d ",sum(50));
return 0;
}
Since sum (variable) is getting value 0 each time it (sum function) is run!
No, it's not.
But for some reason, after the second time the function is called, the first line static int sum = 0; is skipped. Why?
It is not skipped. That is just your impression. But the initialization of 0 happens only once prior to program startup.
If the function is called everytime there's a call to sum(), why doesn't sum (variable) gets the value of 0, since it is written in the beginning of the function?
Because sum is qualified with the static storage class specifier, which means that the sum variable is not destroyed after the function has been executed once and it retains its value for the whole entire program execution.
An object whose identifier is declared without the storage-class specifier_Thread_local, and either with external or internal linkage or with the storage-class specifier static, has static storage duration. Its lifetime is the entire execution of the program and its stored value is initialized only once, prior to program startup.
Source: ISO/IEC 9899:2018 (C18), §6.2.4/3
Omit static at the sum variable and you get your desired result.
Note that the purpose of the sum function is pretty useless in that way. I guess it is just for testing purpose only.
EDIT:
For me it seems that you actually got the function from somewhere else and misunderstood the purpose of the program and the function sum.
The original purpose of the function sum is to sum the input values provided at different function calls to sum() and return the current sum at each function call.
That is the reason, why sum (variable) is qualified with static (to retain its value).
The purpose is not to just pass the input value through, which is what think the purpose of sum() is.

Can the post-increment operator be used in the parameters of a function call? in C?

My question pertains to function calls in general, but I thought of it
while I was writing a priority queue using a heap. Just to give some context (not that it matters much) my heap stores items top to bottom left to right and I represent the heap as an array of structures. Upon inserting a new item, I just put it in the last place in the heap and then call the function "fix_up" at the bottom which will move the item to the proper place in the heap. I am wondering if instead of doing...
fix_up(pQueue->heap, pQueue->size);
pQueue->size++;
...I could just do...
fix_up(pQueue->heap, pQueue->size++);
I am unsure as to if this is ok for a few reasons.
1) Since pQueue->size is in the function call, I'm not even sure if it's actually pQueue->size or rather a copy of the integer stored in pQueue->size. If it was a copy then obviously I wouldn't be adding 1 to the actual pQueue->size so there'd be no point in doing this.
2) Since it's a function call, it is going to then go into the function fix_up and execute all the code there. I am wondering if this would have an unintended consequence of maybe when it went to fix_up it would get incremented by 1 and my index would be 1 higher than I intended while executing fix_up? Or would it do what it's supposed to do and wait until after fix_up had finished executing?
3) Even if it is ok, is it considered a good coding practice for C?
Status priority_queue_insert(PRIORITY_QUEUE hQueue, int priority_level, int data_item)
{
Priority_queue *pQueue = (Priority_queue*)hQueue;
Item *temp_heap;
int i;
/*Resize if necessary*/
if (pQueue->size >= pQueue->capacity) {
temp_heap = (Item*)malloc(sizeof(Item) * pQueue->capacity * 2);
if (temp_heap == NULL)
return FAILURE;
for (i = 0; i < pQueue->size; i++)
temp_heap[i] = pQueue->heap[i];
pQueue->capacity *= 2;
}
/*Either resizing was not necessary or it successfully resized*/
pQueue->heap[pQueue->size].key = priority_level;
pQueue->heap[pQueue->size].data = data_item;
/*Now it is placed as the last item in the heap. Fixup as necessary*/
fix_up(pQueue->heap, pQueue->size);
pQueue->size++;
//continue writing function code here
}
Yes you can.
However, you cannot do this:
foo(myStruct->size++, myStruct->size)
The reason is that the C standard does not say in which order the arguments should be evaluated. This would lead to undefined behavior.
1) Since pQueue->size is in the function call, I'm not even sure if it's actually pQueue->size or rather a copy of the integer stored in pQueue->size. If it was a copy then obviously I wouldn't be adding 1 to the actual pQueue->size so there'd be no point in doing this.
Whatever argument you're sending to a function, it will be evaluated before the function starts to execute. So
T var = expr;
foo(var);
is always equivalent to
foo(expr);
2) Since it's a function call, it is going to then go into the function fix_up and execute all the code there. I am wondering if this would have an unintended consequence of maybe when it went to fix_up it would get incremented by 1 and my index would be 1 higher than I intended while executing fix_up? Or would it do what it's supposed to do and wait until after fix_up had finished executing?
See above
3) Even if it is ok, is it considered a good coding practice for C?
Somewhat subjective, and a bit OT for this site, but I'll answer it anyway from my personal view. In general, I would try to avoid it.
Though, the other posts already answer this question, but none of them talk about role of Sequence Point, in this particular case, which can greatly help in clarifying OP's doubt.
From this [emphasis mine]:
There is a sequence point after the evaluation of all function arguments and of the function designator, and before the actual function call.
From this [emphasis mine]:
Increment operators initiate the side-effect of adding the value 1 of appropriate type to the operand. Decrement operators initiate the side-effect of subtracting the value 1 of appropriate type from the operand. As with any other side-effects, these operations complete at or before the next sequence point.
Also, the post increment operator increase the value of operand by 1 but the value of the expression is the operand's original value prior to the increment operation.
So, in this statement:
fix_up(pQueue->heap, pQueue->size++);
the value of pQueue->size will be increased by 1 before the fix_up() function call but the argument value will be the original value prior to the increment operation.
Yes you can use it directly in the expression you pass as argument.
A statement like
fix_up(pQueue->heap, pQueue->size++);
is somewhat equivalent to
{
int old_value = pQueue->size;
pQueue->size = pQueue->size + 1;
fix_up(pQueue->heap, old_value);
}
A note about the "equivalent" example above. Since the order of evaluation of arguments to function calls is not specified, the actual increment of pQueue->size could happen after the call to fix_up. And it also means that using pQueue->size more than once in the same call would lead to undefined behavior.
Yeah you can use it in function calls, but please note that your two examples are not equivalent. The pQueue->heap argument may be evaluated before or after pQueue->size++ and you can't know or rely on the order. Consider this example :
int func (void)
{
static int x = 0;
x++;
return x;
}
printf("%d %d", func(), func());
This will print 1 2 or 2 1 and we can't know which we'll get. The compiler need not evalute the function parameters consistently throughout the program. So if we add a second printf("%d %d", func(), func()); we could get something like 1 2 4 3 as output.
The importance here is to not write code which relies on order of evaluation. Which is the same reason as mixing ++ with other operations or side-effects in the same expression is bad practice. It can even lead to undefined behavior in some cases.
To answer your questions:
1) Since pQueue->size is in the function call, I'm not even sure if it's actually pQueue->size or rather a copy of the integer stored in pQueue->size. If it was a copy then obviously I wouldn't be adding 1 to the actual pQueue->size so there'd be no point in doing this.
The ++ is applied to the variable in the caller, so this isn't an issue. The local copy of the variable happens during function call, independently of the ++. However, the result of a ++ operation is not a so-called "lvalue" (addressable data), so this code is not valid:
void func (int* a);
...
func(&x++);
++ takes precedence and is evaluted first. The result is not an lvalue and cannot have its address taken.
2) Since it's a function call, it is going to then go into the function fix_up and execute all the code there. I am wondering if this would have an unintended consequence of maybe when it went to fix_up it would get incremented by 1 and my index would be 1 higher than I intended while executing fix_up? Or would it do what it's supposed to do and wait until after fix_up had finished executing?
This isn't an issue unless the function modifies the original variable through a global pointer or such. In that case you would have problems. For example
int* ptr;
void func (int a)
{
*ptr = 1;
}
int x=5;
ptr = &x;
func(x++);
This is very questionable code and x will be 1 after the line func(x++); and not 6 as one might have expected. This is because the function call expression is evaluated and finished before the function call.
3) Even if it is ok, is it considered a good coding practice for C?
It will work ok in your case but it is bad practice. Specifically, mixing the ++ or -- operators together with other operators in the same expression is bad (although common) practice, since it has a high potential for bugs and tends to make code less readable.
Your original code with pQueue->size++; on a line of it's own is superior in every way - stick with that. Contrary to popular belief, when writing C, you get no bonus points for "most operators on a single line". You may however get bugs and maintenance problems.

C method should call itself recursive twice, but doesn't seem to do it

I'm relatively new to C and I've got the following problem:
I'm trying to build a Satsolver using the DPLL alogrithm.
I guess you don't have to know the algorithm or problem to answer my question.
The DPLL method trys some stuff and calls itself twice at the end like this:
return (DPLL(newarray[0], variables, &newclauses))
|| (DPLL(newarray2[0], variables, &newclauses2));
The idea of it is, that at the end there are two new arrays. One gets a new value, the other one gets the negated value.
My problem is: The algorithm doesn't seem to check the second method call
DPLL(newarray2[0], variables, &newclauses2
Because the whole algorithm returns 0, if
(DPLL(newarray[0], variables, &newclauses2)
is 0. It's fine that it returns 1, if the first call is 1.
The DPLL is called from my main method like this:
if (DPLL(phi, variables, &claues))
{
printf("%s\n", "SATISFIABLE");
}
else
{
printf("%s\n", "UNSATISFIABLE");
}
Is it even possible in c to do the recursive calls it like this?
The reason the second call may not happen is because of short circuit evaluation. If the first call returns a true value the entire expression is true and so there is no need to evaluate the second call. If you want to guarantee that both are called you could do this:
int r1 = DPLL(newarray[0], variables, &newclauses);
int r2 = DPLL(newarray2[0], variables, &newclauses2);
return r1 || r2;
In this case both calls are completed before any short circuiting happens in the return. However, short circuit evaluation is a good optimization in the example you gave.
I think the problem is short-circuiting - in an expression of type a || b, b is only evaluated if a is false. This is mandated by the C++ rules (the standard).
In your case, if the first call to DPLL returns true, the second call won't executed.
You'll need to refactor your code as:
bool a1 = DPLL(newarray[0], variables, &newclauses);
bool a2 = DPLL(newarray2[0], variables, &newclauses2);
return a1 || a2;
thanks for your answers!
But that doesn't quite do it. It seems, that the algorithm just goes to the full depth of the first one, whatever that one is. I tried to do it like you proposed, but it gave me a 0, where a 1 was expected. Funny thing is that when I turn around the function calls, so that the call that would return a 1 comes first, it works. But then it doesn't work for ohter files anymore.

Call an expression multiple times in an expression

I'm a student and new to C. One of the questions for my homework reads as follows:
max is a function that accepts two int parameters and returns the
value of the larger one. Four int variables, population1 ,
population2 , population3 , and population4 have already been
declared and initialized. Write an expression (not a statement!)
whose value is the largest of population1 , population2 ,
population3 , and population4 by calling max . (HINT: you will need
to call max three times and you will need to pass the return values
of two of those calls as arguments to max . REMEMBER: write an
expression, not a statement.)
I understand the logic of it:
Call the function max with the first two variables, the function will return the larger of the two and then take that value (somehow pass it without assigning to a fifth declared variable) and compare it to the third variable's value. Take the larger of the second pairing (again passing it without the benefit of a new variable - remember it's an expression, not a statement) and compare it to the forth value. However I haven't been able to write the correct syntax.
Also, understand that this is a 100 level class. So anything higher level will not be accepted for this particular question. No libraries to be #include(d).
Well you seem to understand how to do it, and yes the question seems to ask you to not assign returned values to new varibles. You can basically chuck in a max() as a parameter to another max(), and the return of the inner max() will be the int for the outer max() parameter.
Since c is strict, it won't compile unless the return type for the function is the same as the parameter (in this case, both are int, so it's fine)
max(2, max(3, 4)); // inner returns 4, which puts 4 into the outer max, and compares 2 to 4
Function calls can be nested. Here's a hint:
max(population1, max(...))
Can you come up with the correct code for the ...?
A function which returns something different that nothing (void) can be used inside an expression freely. An expression is defined recursively since it is made by sub-expressions until you reach terminal symbols (as constants or function calls).
So there is nothing strange in understanding the syntax, a call to max is synctatically equivalent to a numeric constant.
int x = 5;
int y = max(5,10);
int z = 5 + 10;
int k = max(5,10) + 3;
int j = max(3 + 2, 8);
These are all legal. Of course the assignment is just for clarity, as as assignment is a statement, not just an expression anymore.

This code is giving an absurd answer [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
What is really happening in this code?
I have a code which includes a recursive function. I have wasted a lot of time on recursion, but i still couldn't get it, really:
#include<stdio.h>
count(int);
main(){
int x=10,z;
z=count(x);
}
count(int m){
if(m>0)
return count(m-1);
}
When count is called for the first time with argument 10, it fulfils the condition and the recursion starts. What happens really when a function calls itself? I dont get it. What does the statement return count(m-1) mean? Where does it tranfer the control?
The return value of the function count is undefined, because there is no default return if (m <= 0) is true.
C11, § 6.9.1 Function definitions
If the } that terminates a function is reached, and the value of the
function call is used by the caller, the behavior is undefined.
Besides, to understand how a recursive function works, you have to take a paper and try to execute the code by yourself (see also here).
You need count to return something when m <= 0. You should declare the return type of count and compile with -Wall so the compiler will help you find mistakes in your code.
recursion means that the function will call itself, mostly at the end of itself, if it's tail recursion.
So your count function checks that the input argument is > 0 and then if it is, it will call count(m-1). Now it starts at the top of count with m=9. It does the same thing, and then calls count with m=8, etc.
Until the end condition is reached, which should normally be explicitly catered for in your function, such as if (m == 0) return m; or some such thing. At that point the recursion ends and the function terminates.
Also, count should have a return type, such as int count (int m)
what does the statement return count(m-1) mean ? where does it tranfer the control?
That seems to be your only question.
it means that it is calling "count" with the value m-1. So if m was 10, then it is calling "count" with 9.
It is transferring the control recursively to the count method.
You also don't have a return for the every possible path in the "count" method.
What happens if m is <= 0?

Resources