Is compound if checking for null and then other condition in C always safe? [duplicate]

喜你入骨 提交于 2019-12-11 12:58:25

问题


(this question is an exact copy of Is compound if checking for null and then other condition in C++ always safe? but about C, not C++. It was pointed out that the question should be more specific).

I have been using the following type of if condition for a lot of time.

char* ptr = ...;
if (ptr != NULL && ptr[0] != '\0') // <=== is this always safe?
{ /* ... */ }

It relies on ptr != NULL being checked before ptr[0] !='\0'.

Is it safe under all standards, compilers, architectures? Or is there a possibility that ptr[0] != '\0' will be checked before ptr != NULL?


回答1:


Yes, it is safe.

C standard says (N1570 - 6.5.13 Logical AND operator):

Unlike the bitwise binary & operator, the && operator guarantees left-to-right evaluation; if the second operand is evaluated, there is a sequence point between the evaluations of the first and second operands. If the first operand compares equal to 0, the second operand is not evaluated.




回答2:


If ptr is a built in type then this is always safe. The compiler must evaluate the left hand side first and only evaluate the right hand side if the left side is true.

If ptr is a user defined type (which it isn't here) then this may not apply as operator&& can be overridden in the class and it DOES NOT short circuit like this.




回答3:


Yes its safe. It's called short-circuit evaluation and applies to the logical-and and logical-or operators.

In logical-and (&&) the right side is only evaluated if the left side is true.

In logical-or (||) the right side is only evaluated if the left side is false.




回答4:


The other answers already explain how short circuit evaluation guarantees that the code is safe - however, this only holds for a single thread.

If there are multiple threads executing the same code, and ptr is not using thread-local-storage, it may well be that in

ptr != NULL && ptr[0] != '\0')

You have a sequence like:

  • Thread 1 verifies that ptr != NULL is true.
  • Thread 2 assigns ptr = NULL
  • Thread 1 attempts to access ptr[0] and segfaults.



回答5:


In your question, you write char* ptr = ....

So the answer depends on the context in which you assign ptr with a value.

As long as you assign ptr either with a valid memory address or with NULL, then it should be safe.

But if you assign ptr with an invalid memory address which is not NULL, then your code is unsafe.

For example:

char* ptr = func();

char* func()
{
    char* str; // possibly pointing to an invalid memory address which is not NULL
    return str;
}


来源:https://stackoverflow.com/questions/21776657/is-compound-if-checking-for-null-and-then-other-condition-in-c-always-safe

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!