gnu C condition of "if" - c

we got if(expression) {...} for example. We all know if expression is true, it will execute lines in braces. But what is "True" in C?
Is that != 0 means true as I think?
Thank you

Here is what the standard has to say.
§6.8.4 Selection statements
Syntax
selection-statement:
if ( expression ) statement
if ( expression ) statement else statement
switch ( expression ) statement
§6.8.4.1 The if statement
Constraints
The controlling expression of an if statement shall have scalar type.
Semantics
In both forms, the first substatement is executed if the expression compares unequal to 0. In the else form, the second substatement is executed if the expression compares equal to 0. If the first substatement is reached via a label, the second substatement is not executed.
An else is associated with the lexically nearest preceding if that is allowed by the
syntax.

Any none-zero result tests as true.

Yes, true is not-null in C and C++.

Related

SQL SERVER and NULL values on Equal operator

I have in a where clause the following statement COLUMN_1 <> 'O'
But the rows that contains NULL on the COLUMN_1 are not take in consideration, it is like they contain the value 'O'
Why is that ?
Thanks in advance.
Because NULL does not equal, nor does not not equal anything, including NULL. NULL <> 'O' evaluates to UNKNOWN; which is specifically not TRUE.
If you want to evaluate with NULL values you need to use IS NULL:
WHERE (COLUMN_1 <> 'O' OR COLUMN_1 IS NULL)
This is also documented on both not-equal operator articles:
Not Equal To (Transact SQL) - traditional
Compares two expressions (a comparison operator). When you compare nonnull expressions, the result is TRUE if the left operand is not equal to the right operand; otherwise, the result is FALSE. If either or both operands are NULL, see the topic SET ANSI_NULLS (Transact-SQL).
Not Equal To (Transact SQL) - exclamation
Tests whether one expression is not equal to another expression (a comparison operator). If either or both operands are NULL, NULL is returned. Functions the same as the <> (Not Equal To) comparison operator.

Making the conditional operators behave like if/else statements in C

Is it possible to make the ?: operator process several statements like in the example below?
condition ? FirstTrueExpression SecondTrueExpression : FirstFalseExpression SecondFalseExpression
And is there a way to avoid specifying the 'else' statement?
condition ? TrueExpression
You can use comma operator , to concatenate multiple expressions.
The expressions are evaluated from left to right and its resulting type and value will be ones of the righthand expression.
condition ? FirstTrueExpression, SecondTrueExpression : (FirstFalseExpression, SecondFalseExpression)
Note that you need () around (FirstFalseExpression, SecondFalseExpression) due to the operator precedence while you don't need () around FirstTrueExpression, SecondTrueExpression.
You can use
condition && TrueExpression
instead of
condition ? TrueExpression
This is thanks to short-circuit evaluation of logical and && operator:
When condition is false, condition && TrueExpression will be false (0) regardless of the value of TrueExpression, and therefore TrueExpression isn't evaluated.
When condition is true, TrueExpression is evaluated because it is needed to determine the value of condition && TrueExpression.

Invalid length parameter passed to the substring function case

I have an issue with substring function while using it inside case statement.
select
case when -1<0 then 'ok' else SUBSTRING('abcd',1,-1) end
gives me an issue:
Invalid length parameter passed to the substring function.
Why is the case "looking" at the else condition since the first condition is met?
On the other hand query:
declare #a int;
set #a=-1
select
#a,
case when #a<0 then 'ok' else SUBSTRING('abcd',1,#a) end
presents the right answer 'ok' without any errors.
The problem is that the literal value of -1 is parsed by the compiler before run-time for the length parameter. The compiler knows that -1 is invalid, as length must have a positive value, so the error is flagged before the SQL is even run.
In the latter statement, the length passed is a variable. At compile time, the variable has an "unknown" value, as it's not SET till run time, thus the syntax is fine.
Simply put, the compiler knows that a length of -1 for SUBSTRINGis invalid, regardless of if that SQL will actually run, and so errors.
Unlike other functions, such as STUFF and REPLICATE, which state "If length is negative, a null string is returned.", SUBSTRING, LEFT, and RIGHT all state: "If integer_expression is negative, an error is returned." For a literal value, it appears that the compiler is checking these values, even if they will never be used, and then flagging the error.
This isn't limited to logic within a CASE either. For example, the using logical flow operators such as IF generates the same behaviour:
IF 1 = 0
SELECT LEFT('abc',-1)
As does the ISNULL function:
SELECT ISNULL('ok',RIGHT('abc',-1));
It only, however, occurs with literal values. If, for example, you were to use the values from a column, the behaviour is not seen:
IF 1 = 0
SELECT SUBSTRING('abc',1,n) FROM (VALUES(1),(-1)) V(n);
This does not return an error, even though everything in VALUES is a literal. That is because the value of n has not been evaluated.
You can try this as it needed positive end values as length can not be in negative but can be 0.
select
case when -1 < 0 then 'ok' else SUBSTRING('abcd',1, 1) end

SSIS Case Statement not working

This SSIS case expression looks perfectly valid to me, but it's coming up red. Can anybody explain why?
[Copy of "final_benefit_type_grouper"] == "MEDICAL" ? "2"
Probably because you don't have the " : {ELSE} " part of the expression. What do you want the value to be if the column does not equal "MEDICAL"?
Referring to the Microsoft Documentation, ? conditional syntax is like the following:
boolean_expression?expression1:expression2
"If the Boolean expression evaluates to TRUE, then the first expression is evaluated and the result is the expression result. If the Boolean expression evaluates to FALSE then the second expression is evaluated and its result is the expression result." Read more
so i think you are missing the second part of the expression, i might be something like this:
[Copy of "final_benefit_type_grouper"] == "MEDICAL" ? "2" : ""
Also it is better to add a NULL checking to your expression using ISNULL() function (to avoid a null value exception):
ISNULL([Copy of "final_benefit_type_grouper"])? "" : ( [Copy of "final_benefit_type_grouper"] == "MEDICAL" ? "2" : "")
It is also to follow this Link to Read more about write a case statment using a SSIS expression

Postgres NOT in array

I'm using Postgres' native array type, and trying to find the records where the ID is not in the array recipient IDs.
I can find where they are IN:
SELECT COUNT(*) FROM messages WHERE (3 = ANY (recipient_ids))
But this doesn't work:
SELECT COUNT(*) FROM messages WHERE (3 != ANY (recipient_ids))
SELECT COUNT(*) FROM messages WHERE (3 = NOT ANY (recipient_ids))
What's the right way to test for this condition?
SELECT COUNT(*) FROM "messages" WHERE NOT (3 = ANY (recipient_ids))
You can always negate WHERE (condition) with WHERE NOT (condition)
You could turn it around a bit and say "3 is not equal to all the IDs":
where 3 != all (recipient_ids)
From the fine manual:
9.21.4. ALL (array)
expression operator ALL (array expression)
The right-hand side is a parenthesized expression, which must yield an array value. The left-hand expression is evaluated and compared to each element of the array using the given operator, which must yield a Boolean result. The result of ALL is "true" if all comparisons yield true (including the case where the array has zero elements). The result is "false" if any false result is found.
Beware of NULLs
Both ALL:
(some_value != ALL(some_array))
And ANY:
NOT (some_value = ANY(some_array))
Would work as long as some_array is not null. If the array might be null, then you must account for it with coalesce(), e.g.
(some_value != ALL(coalesce(some_array, array[]::int[])))
Or
NOT (some_value = ANY(coalesce(some_array, array[]::int[])))
From the docs:
If the array expression yields a null array, the result of ANY will be null
If the array expression yields a null array, the result of ALL will be null
Augmenting the ALL/ANY Answers
I prefer all solutions that use all or any to achieve the result, appreciating the additional notes (e.g. about NULLs). As another augementation, here is a way to think about those operators.
You can think about them as short-circuit operators:
all(array) goes through all the values in the array, comparing each to the reference value using the provided operator. As soon as a comparison yields false, the process ends with false, otherwise true. (Comparable to short-circuit logical and.)
any(array) goes through all the values in the array, comparing each to the reference value using the provided operator. As soon as a comparison yields true, the process ends with true, otherwise false. (Comparable to short-circuit logical or.)
This is why 3 <> any('{1,2,3}') does not yield the desired result: The process compares 3 with 1 for inequality, which is true, and immediately returns true. A single value in the array different from 3 is enough to make the entire condition true. The 3 in the last array position is prob. never used.
3 <> all('{1,2,3}') on the other hand makes sure all values are not equal 3. It will run through all comparisons that yield true up to an element that yields false (the last in this case), to return false as the overall result. This is what the OP wants.
an update:
as of postgres 9.3,
you can use NOT in tandem with the #> (contains operator) to achieve this as well.
IE.
SELECT COUNT(*) FROM "messages" WHERE NOT recipient_ids #> ARRAY[3];
not (3 = any(recipient_ids))?
Note that the ANY/ALL operators will not work with array indexes. If indexes are in mind:
SELECT COUNT(*) FROM "messages" WHERE 3 && recipient_ids
and the negative:
SELECT COUNT(*) FROM "messages" WHERE NOT (3 && recipient_ids)
An index can then be created like:
CREATE INDEX recipient_ids_idx on tableName USING GIN(recipient_ids)
Use the following query
select id from Example where NOT (id = ANY ('{1, 2}'))

Resources