On Undefined Behavior

2019-02-08 18:00发布

Generally, UB is regarded as being something that has to be avoided, and the current C standard itself lists quite a few examples in appendix J.

However, there are cases where I can see no harm in exploiting UB other than sacrificing portability.

Consider the following definition:

int a = INT_MAX + 1;

Evaluating this expression leads to UB. However, if my program is intended to run on a, say, 32-bit CPU with modular arithmetic representing values in Two's Complement, I'm inclined to believe that I can predict the outcome.

In my opinion, UB is sometimes just the C standard's way of telling me: "I hope you know what you're doing, because we can't make any guarantees on what will happen."

Hence my question: is it safe to sometimes rely on machine-dependent behavior, even if the C standard considers it to invoke UB, or is "UB" really to be avoided, no matter what the circumstances are?

7条回答
迷人小祖宗
2楼-- · 2019-02-08 18:33

No.

The compiler take advantage of undefined behavior when optimizing the code. A well-known example is the strict overflow semantics in GCC compiler (search for strict-overflow here) For example, this cycle

for (int i = 1; i != 0; ++i)
  ...

supposedly relies on your "machine dependent" overflow behavior of signed integer type. However, the GCC compiler under the rules of strict overflow semantics can (and will) assume that incrementing an int variable can only make it larger, and never smaller. This assumption will make GCC optimize-out the arithmetics and generate an endless cycle instead

for (;;)
  ...

since this is a perfectly valid manifestation of undefined behavior.

Basically, there's no such thing as "machine-dependent behavior" in C language. All behavior is determined by the implementation and the level of implementation is the lowest level you can ever get to. Implementation isolates you from the raw machine and isolates you perfectly. There's no way to break through that isolation and get to the actual raw machine, unless the implementation explicitly permits you to do so. Signed integer overflow is normally not one of those contexts where you are allowed to access the raw machine.

查看更多
登录 后发表回答