This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Double Negation in C++ code
While reading one code I read:
flush = ! !(flags & GST_SEEK_FLAG_FLUSH);
I am not getting what does !! mean here .
what does this sentence do?
EDIT:
I got it its a double-negative. trick to convert non-bool data to bool
But what is the need of that? Here flush is bool then if you assign any non zero item to bool it will treat as 1 and zero item as 0 so whats benefit of doing this?
It's a double-negative. It's a way of converting an otherwise-non-bool expression (such as flags & GST_SEEK_FLAG_FLUSH) to a bool. I personally prefer:
flush = (flags & GST_SEEK_FLAG_FLUSH) != 0;
If flush is boolean variable, and you force some non-boolean value to it, some compiler will generate a warning forcing value to bool 'true' or 'false'. So it's safer to use double negation.
Some compilers (like Visual Studio) will warn when coercing a non-boolean type to an int, for example:
#include <stdio.h>
int main(void) {
int x = 10;
bool y = x; // warning C4800: 'int' : forcing value to bool 'true' or 'false' (performance warning)
return 0;
}
The double-negation trick is one way of converting to bool and preventing this warning, however I would lean towards the != 0 check Jim Buck recommended for clarity.
Just wanted to add a little example for you that might clear things.
main()
{
int i=10;
printf("%d",!!i);
}
Output is 1
Related
I was playing around with bool variables. I am aware that boolean is used to represent a true (any other number besides 0) or false (the number 0). I realized that the variables create random integer numbers. I was wondering if one can one use boolean variables to generate random numbers? Can someone please elaborate on this behaviour caused by the keyword boolean?
My code is as follows:
#include<stdio.h>
#include<stdbool.h>
int main()
{
bool a,b,c,d,e,f,g,h,i,j,k;
printf("%d\n",a);
printf("%d\n",b);
printf("%d\n",c);
printf("%d\n",d);
printf("%d\n",e);
printf("%d\n",f);
printf("%d\n",g);
printf("%d\n",h);
printf("%d\n",i);
printf("%d\n",j);
printf("%d\n",k);
}
This is not behaviour specific to a bool. This is caused because you are using an uninitialized variable. This is not only not random, it is not safe. This is undefined behaviour, you should avoid it at all costs.
Boolean is not randomly defined. These variables take false as default value. In compiler. The default value is consistent rather than random 0 or 1 from time to time.
Today I encountered a problem with scanf functions. Assume that you have a structure like the following example.
struct structA{
bool bVal;
int nVal;
}
If you run the following code
structA a;
a.nVal = 7;
...// Assume that we read a text file and the only text is "0"
fscanf(fp,"%d",&a.bVal);
printf("\n a.bVal=%d",a.bVal);
printf("\n a.nVal=%d",a.nVal);
It will print
a.bVal = 0
a.nVal = 0
The reason is that the fscanf function assumes a.bVal is an integer and overwrites the a.nVal first 3 bytes. This problem can be solved by the following dirty solution.
structA a;
a.nVal = 7;
...// Assume that we read a text file and the only text is "0"
int nBVAL;
fscanf(fp,"%d",&nBVAL);
a.bVal = nBVAL;
printf("\n a.bVal=%d",a.bVal);
printf("\n a.nVal=%d",a.nVal);
My question is that is there a cleaner and straightforward way of avoiding this problem beside the solution explained?
The solution you're proposing is the only portable one.
There is no conversion specifier for _Bool. There's also no guarantee about the storage size of a _Bool, except that it has at least CHAR_BIT bits. Even if you knew the size and tried something like %hhd, entering anything other than 1 or 0 would create a value that's invalid for a _Bool (scanf() would access the object through a char pointer, possibly writing the padding bits of the _Bool).
The only safe thing to do is to take input of a type you can handle and convert this to a _Bool where needed, as you're doing in your example.
Note there's no similar problem with printf(). A _Bool passed to printf() is promoted to int, so %d is fine.
From this answer, I saw this:
unsigned long
hash(unsigned char *str)
{
unsigned long hash = 5381;
int c;
while (c = *str++)
hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
return hash;
}
The problem is that I don't see how the while stops from executing. Generally an assignment isn't resulted in true? I mean if(a = 5) will be true.
Also the compiler gave me this warning:
warning: suggest parentheses around assignment used as truth value [-Wparentheses]
Can anyone step me trough on what exactly goes on with the loop? I would strongly suggests that an example would be the best approach here.
Also where should the parentheses go to make this more clear?
The value of an assignment is the value that gets assigned. For example, this code:
int a;
printf("%d\n", a=5);
… will print out 5.
So, this loop runs until c is assigned something false.
And in C, 0 is false, and strings are null-terminated, so at the end of the string, the NUL character, 0, will end the loop.
The warning is because if (a = 5) is a typo for if (a == 5) more often than it's intentional code. Putting extra parentheses around an assignment, like if ((a == 5)), is an idiomatic way to say "I meant to use the value of this assignment". With some compilers, you may get a different, stronger warning in the case where the value is constant, as in my example, than in examples like yours, but the issue is the same: if you meant to test the value of an assignment, and you don't want to disable the warning globally, the way to convince GCC to leave you along is with extra parentheses: while ((c = *str++)).
See this question for more details. You may also want to search the GCC mailing lists for threads like this one discussing the warning.
I have to write a function that calculates the floor of log base 16 of an unsigned int passed in. There are restrictions as to what operators and what constants we are allowed to use, and we can only use specifically for loops.
For clarity, we cannot use any conditional statements(if, else, switch ... ). The function prototype is:
int floor_log16(unsigned int x);
Allowed operators: ++ -- = & | ~ ^ << ! >>
Allowed constants: 1 2 3 4 8 16
I wrote a version of the program as follows:
int floor_log16(unsigned int x) {
int index=1;
int count=(1!=1);
count--;
for(; index<=x; index<<=4) {
count++;
}
return count;
}
which seems to work as desired. However, I realized that based on the later functions and description of the needed functionality we have to write, I noticed that under "allowed operators" sometimes > and < were listed.
I deduce this implies that since for the floor_log16 function listed above, we weren't explicitly told to use > or <, I can only assume that the solution posted above will not be accepted.
This leaves me rather confused because I don't understand how you can possibly have a for loop without a boolean check?
Isn't the whole idea of a loop to iterate while a condition is met?
Well, first of all, for-loop without the boolean check is perfectly fine. For example,
for (;;)
is a common way of writing
while (true)
Second, having a for-loop with other parts but without boolean check is still useful as you can exit it with return or break.
And the last thing. There are tons of ways of getting a boolean without using < and >. For example, you can simply use i to check that i != 0 and so on.
For example if you want to check that a < b you can check for (a - b) < 0 instead. Implementing addition (and hence subtraction) with bitwise operators is a well known interview question (you should really try to do this yourself, it's fun), and checking that your int is negative is as easy as looking at its most significant bit.
I don't like to spoil your task but consider about for condition like 'comparison to 0'. This doesn't require any explicit operator. One of possible way to get it is something like this:
// This cycle will end as soon as index is 0.
for (;index; index = (index >> 4))
{
// ...
}
If you XOR any unsigned with itself, it becomes 0. So int count=(1!=1); could be changed to int count = 1 ^ 1.
As for the loop condition, Roman's idea of comparison to 0 seems like the most natural way to go.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Error checking a function that returns an int
I have an integer function that returns an integer in a wide range (in C).
How should I handle invalid inputs? I mean what should it return if the input is invalid?
Sorry If this question is too basic. I'm not experienced and couldn't find the answer anywhere else.
Depends on the value range. For example, if your function is only expected to return positive values on success, return -1 for an error. If it normally only returns values >0, then return 0 on error.
If it returns any possible value in the int range, then you may need a different approach, for example
bool GetValue(int inputValue, int *outResult);
where your function stores the result in outResult, or returns false if an error occurred.
Does your output range into the negative numbers? If not, -1 is a reasonably standard code to return. Where are you getting the input from?
Where is this input coming from? I assume from a user or file. Forget whatever the goddamned C function wishes to return to a call, I recommend doing a check if the input is an int at the beginning of the function:
if (userinput/1.00 == (int)userinput)
We have an integer! Rest of the function goes here...
else
Do something else like abort the function and change the 'input'...
Please excuse any inefficient/incorrect code, I myself am I programming noob.
There really isn't any standard way for all cases. -1 is a common "generic error" return value. You can also do a bunch of defines like this:
#define MEMORY_ERROR 1
#define OUT_OF_BOUNDS 2
#define ... 3
etc...
and then you can use do this:
int func()
{
...
...
if(condition) {
// Error handling
return MEMORY_ERROR;
}
...
if(condition) {
// Error handling
return OUT_OF_BOUNDS;
}
}
or something like it.
my preference, when writing code in a language that lacks exception handling, is to always use the return value as an error indicator.
int get_value(int *value)
{
if ( input_ok )
*value = input;
return 0;
return -1;
}
this does not seem practical since it forces you to use intermediate variables to store function results, but it proved useful so many times to catch errors and handle them correctly (you can never rely on user input).
also, you should note that having a special value to show an error is not a good idea: you never know what will happen with your code. if later you want to add a new feature and unfortunately the special value is useful for this feature, what will you do ? write a new function with another special error value ? what if the input should cover the whole range of the return type ? if this is part of a bigger project, how can you make sure that every programmer that may use your function is aware of the special value ?
so err on the safe side: don't use a special value and use a dedicated error handling path.
note that you can reverse the above code and write int get_value(int *error);