what actually happens in if statement here?
#include <stdio.h>
int x;
void main()
{
if (x)
printf("hi");
else
printf("how are u");
}
printf("hi"); is ran if x is non-zero, and printf("how are u"); runs if x is zero.
The conditional check formally uses an int type in C (with any other type implicitly converted to an int prior to the evaluation); not a Boolean type.
Note that x is initialised automatically to 0 in your case as it's at global scope.
Here
if (x)
takes the first branch if x is not 0, otherwise the second (else) branch.
In C any non zero value is equivalent to the truth and zero to false
So any value is considered as valid logical (even pointers).
int *p = malloc(40);;
if (p) printf("Good!!");
in your example x will be equal zero (unitialized global variables are zeroed) and the else printf will be executed.
As the any value which can be converted to integer is valid as logical we can write very short functions like this:
char *strcpy(char *dest, const char *src)
{
char *saveddest = dest;
while(*dest++ = *src++);
return saveddest;
}
Here int x; is a global uninitialized variable. Compiler initialized the global int variable with 0. In C, 0 means false and 1 means true. Thats why it will print the else part because if(0) means false and compiler will execute the else block i.e. how are u.
Please visit the link for better understanding:
https://www.geeksforgeeks.org/g-fact-53/
Related
This is for programming in C.
Say I had the follow code in my program:
int fun1(int x);
int main (void)
{
int a = 5;
a = fun1(10);
}
int fun1(int x)
{
\\Program arbitrarily ends here
return x;
}
In my memory diagram what would the value of a be assuming the program terminates before fun1 is able to return a value? Would the value of a be undetermined (??) or would it be 5?
The value of a is already initialized to 5. Now, according to the condition, you want to know the results of that circumstance when the fun1() ends before it could return a value; assume the following:
int fun1(int x)
{
// return x;
}
Here we've supposed the function quits before returning the value.
You'll still get the output 5 before, during or after execution of the program since it returns nothing but the variable a is preassigned to 5 and it can't be changed to 10 unless the function returns 10 and assigns to the variable.
But remember, if you don't assign anything to a, then it may show an unexpected value (I got 4195638 when used printf() for a).
I dont have time to explain it deeply, its very simple code but the function always return 'y'(=true)
It is expected to write each number from 1 to squareroot of the generated random number and decide whether it is dividable or not but when i run it, somehow the if statement in the function always return true
#include <stdio.h>
#include <stdlib.h>
int a,b,i;
char c;
char abcd(char c);
int main()
{
srand(time(NULL));
int a=rand()%512;
b=sqrt(a);
i=1;
do{
if(abcd(c)=='y')printf("number %d is dividable by %d\n",a,i);
else printf("number %d is not dividable by %d\n",a,i);
i++;
}while(i<=b);
return 0;
}
char abcd(char c)
{
if(a%i==0)return'y';
else return 'n';
}
When you declare int a inside main as
int a=rand()%512;
you are shadowing your global variable a. The a in main is a different variable that has scope only local to the function main. Therefore, when you are using the value a inside char abcd(char c), this value is the global variable a which is default initialized to 0.
Also, why are you passing a char c variable to function abcd. You aren't using it. Please consider renaming your functions to something that more clearly describes their intent.
You have two different variables a:
one declared at file scope
int a,b,i;
and one declared in main():
int a=rand()%512;
Within its scope (almost all of main()), the latter shadows the former. Elsewhere, such as in function abcd(), only the former is visible. The former is default initialized to 0 and no other value is ever assigned to it, so no matter what value i takes, inside abcd(), the expression a%i evaluates to 0.
This is a good lesson in avoiding file-scope variables. Functions should operate on data accessed directly or indirectly through their parameters, or obtained from an external source. It is poor form for functions to exchange data through file-scope variables. Moreover, it was a red flag to me that your function abcd() declares a parameter that it never uses. Suggested variation:
char abcd(int dividend, int divisor) {
return (dividend % divisor) ? 'n' : 'y';
}
Or even better (because better name and more appropriate return type):
_Bool is_divisible(int dividend, int divisor) {
return !(dividend % divisor);
}
The reason yours doesn't work is because the variable a was declared in a separate scope from the abcd function. The a variable you use inside the abcd function is automatically set to 0, which is why it returns true every time (0 % anything is 0).
When you call abcd, you would need to pass a inside the parameters for it to use the correct value.
But really you don't need the abcd function, you can save a lot of code and directly check if it's divisible. This code should work:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
int a, b, i;
char c;
int main()
{
srand(time(NULL));
int a = rand() % 512;
b = sqrt(a);
i = 1;
do {
if (a%i == 0)printf("number %d is dividable by %d\n", a, i);
else printf("number %d is not dividable by %d\n", a, i);
i++;
} while (i <= b);
return 0;
}
#include <stdio.h>
#include <stdlib.h>
int f(int x) {
return x;
}
int main ( int argc,char * argv[]) {
int a=4;
f(a);
printf("PASSED!\n");
return 0;
}
What happens when you call f(a) without assigning it to anything?
What happens when you call a function with return value without assigning it to any variable?
The return value of a function need not be used or assigned. It is ignored (usually quietly).
The function still executes and its side effects still occur.
Consider the 3 functions: int scanf(), int f(), and int printf(), their return values are all ignored yet the functions were still executed.
int a=4;
scanf("%d", &a);
f(a);
printf("PASSED!\n");
It is not good to ignore return values in robust code, especially scanf().
As commented by #Olaf, a warning may be enabled by some compilers.
Explicit ignoring the result of a function is sometime denoted with (void) to quiet that warning.
(void) f(a);
Using your example, we can look at how it evaluates line by line. Starting in main.
int a=4;
We now have a variable a with the value 4.
f(a);
So now the function f is called with a, which has a value of 4. So in the function f, the first parameter is named x and it just returns that parameter x.
So the evaluation of
f(a);
is just
4;
And a program like this compiles and runs perfectly fine.
int main(int argv, char *argv[]) {
1 + 1;
return 0;
}
What happens when you call f(a) without assigning it to anything?
--> Nothing at all.
What happens when you call a function (which has return value) without assigning it to anything?
-->The function will be executed, either make no sense like your case or make a lot of senses like modifying a static variable or a global variable. The return value will be ignored.
The return value will normally be stored in a register and will not fade.
It will be overwritten when the register is needed by the compiler.
If the function is inline it may be detected by the compiler that the value isn't used and ignore the value from being computed at all.
I have a piece of code where I am trying to return the square of the value pointed to by *ptr.
int square(volatile int *ptr)
{
int a,b;
a = *ptr;
b = *ptr;
return a * b;
}
main()
{
int a=8,t;
t=square(&a);
printf("%d",t);
}
Its working fine for me but author of this code said it might not work because of following reason:
Because it's possible for the value of *ptr to change unexpectedly, it is possible for a and b to be different. Consequently, this code could return a number that is not a square!. The correct way to do is
long square(volatile int *ptr)
{
int a;
a = *ptr;
return a * a;
}
I really wanted to know why he said like that?
The idea of the volatile keyword is exactly to indicate to the compiler that a variable marked as such can change in unexpected ways during the program execution.
However, that does not make it a source of "random numbers" - it just advises the compiler - what is responsible for actually changing the variable contents should be another process, thread, some hardware interrupt - anything that would write to the process memory but not inlined in the function where the volatile declaration finds itself. In "older times" (compilers with less magic) everything it did was preventing the compiler from caching the variable value in one of the CPU registers. I have no idea on the optimisations/de-optimistions strategies triggered by it by modern compilers - but it will at least do that.
In the absense of any such external factor, a "volatile" variable is just like any other. Actually - it is just like any other variable - as variables not marked as volatile can also be changed by the same external causes (but the compiled C code would not be prepared for that in this case, which might lead to incorrect values being used).
Since the question has an accepted and correct answer, I will be brief: here is a short program that you can run to see the incorrect behavior happening for yourself.
#include <pthread.h>
#include <math.h>
#include <stdio.h>
int square(volatile int *p) {
int a = *p;
int b = *p;
return a*b;
}
volatile int done;
void* call_square(void* ptr) {
int *p = (int*)ptr;
int i = 0;
while (++i != 2000000000) {
int res = square(p);
int root = sqrt(res);
if (root*root != res) {
printf("square() returned %d after %d successful calls\n", res, i);
break;
}
}
done = 1;
}
int main() {
pthread_t thread;
int num = 0, i = 0;
done = 0;
int ret = pthread_create(&thread, NULL, call_square, (void*)&num);
while (!done) {
num = i++;
i %= 100;
}
return 0;
}
The main() function spawns a thread, and modifies the data being squared in a loop concurrently with another loop calling the square with a volatile pointer. Relatively speaking, it does not fail often, but it does so very reliably in less than a second:
square() returned 1353 after 5705 successful calls <<== 1353 = 33*41
square() returned 340 after 314 successful calls <<== 340 = 17*20
square() returned 1023 after 5566 successful calls <<== 1023 = 31*33
First understand what's volatile: Why is volatile needed in C?
and then, try to find answer by yourself.
It's a game of volatile and hardware world. :-)
Read answer given by Chris Jester-Young:
volatile tells the compiler that your variable may be changed by other means, than the code that is accessing it. e.g., it may be a I/O-mapped memory location. If this is not specified in such cases, some variable accesses can be optimised, e.g., its contents can be held in a register, and the memory location not read back in again.
If there is more than one thread, the value the pointer points to might change inbetween statement "a = *ptr" and statement "b = *ptr". Also: you want the square of a value, why put it into two variables?
In the code you present then there is no way for the variable a that is defined in your main to be modified whilst square is running.
However, consider a multi-threaded program. Suppose that another thread modified the value to your your pointer refers. And suppose that this modification took place after you had assigned a, but before you had assigned b, in the function sqaure.
int square(volatile int *ptr)
{
int a,b;
a = *ptr;
//the other thread writes to *ptr now
b = *ptr;
return a * b;
}
In this scenario, a and b would have different values.
The author is correct (if *ptr will be changed by other threads)
int square(volatile int *ptr)
{
int a,b;
a = *ptr;
//between this two assignments *ptr can change. So it is dangerous to do so. His way is safer
b = *ptr;
return a * b;
}
Because the value of the pointer *ptr might change between the first affection and the second one.
I don't think the value of *ptr can change in this code barring an extremely unusual (and non-standards-compliant) runtime environment.
We're looking at the entirety of main() here and it's not starting up other threads. The variable a, whose address we are taking, is a local in main(), and main() doesn't inform any other function of that variable's address.
If you added the line mysterious_external_function(&a); before the t=square(&a) line, then yes, mysterious_external_function could start a thread and diddle the a variable asynchronously. But there's no such line, so as written square() always returns a square.
(Was the OP a troll post, by the way?)
I see some answers with *ptr can be changed by other threads. But this cannot happen since *ptr is not a static data variable. Its a parameter variable and local and parameter variables being hold inside stack. Each thread has its own stack section and if *ptr has been changed by another thread, it should not effect the current thread's.
One reason why the result might not give the square can be an HW interrupt might happen before assigning b = *ptr; operation as indicated below:
int square(volatile int *ptr) {
int a,b;
a = *ptr; //assuming a is being kept inside CPU registers.
//an HW interrupt might occur here and change the value inside the register which keeps the value of integer "a"
b = *ptr;
return a * b;
}
int i;
int data[5] = {0};
data[0] = i;
What's the value in data[0]?
Also, what's the meaning of this line?
if (!data[0]) { ... }
In most cases, there is no "default" value for an int object.
If you declare int i; as a (non-static) local variable inside of a function, it has an indeterminate value. It is uninitialized and you can't use it until you write a valid value to it.
It's a good habit to get into to explicitly initialize any object when you declare it.
It depends on where the code is written. Consider:
int i;
int data[5] = {0};
void func1(void)
{
data[0] = i;
}
void func2(void)
{
int i;
int data[5] = {0};
data[0] = i;
...
}
The value assigned to data[0] in func1() is completely deterministic; it must be zero (assuming no other assignments have interfered with the values of the global variables i and data).
By contrast, the value set in func2() is completely indeterminate; you cannot reliably state what value will be assigned to data[0] because no value has been reliably assigned to i in the function. It will likely be a value that was on the stack from some previous function call, but that depends on both the compiler and the program and is not even 'implementation defined'; it is pure undefined behaviour.
You also ask "What is the meaning of this?"
if (!data[0]) { ... }
The '!' operator does a logical inversion of the value it is applied to: it maps zero to one, and maps any non-zero value to zero. The overall condition evaluates to true if the expression evaluates to a non-zero value. So, if data[0] is 0, !data[0] maps to 1 and the code in the block is executed; if data[0] is not 0, !data[0] maps to 0 and the code in the block is not executed.
It is a commonly used idiom because it is more succinct than the alternative:
if (data[0] == 0) { ... }
if an integer is declared globally then it is initialized automatically with zero
but if it is local then contains garbage value until and unless itis given some value
If an integer is not initialized, its value is undefined as per C
Since you've included the ={0};, the entire array is filled with zeros. If this is defined outside any function, it would be initialized with zeros even without the initializer. if (!data[x]) is equivalent to if (data[x] == 0).
// File 'a.c'
#include <stdio.h>
void main()
{
int i, j , k;
printf("i = %i j = %i k = %i\n", i, j, k);
}
// test results
> $ gcc a.c
> $ ./a.out
> i = 32767 j = 0 k = 0