对于循环表达结果未使用但代码仍然有效吗?

时间:2014-08-20 01:07:08

标签: c

对于在xcode中未使用的循环表达式结果 但是代码仍然可以工作我不想显示整个循环我只需要最后一个数字就会出现错误警告信息的原因?

#include <stdio.h>

int main(int argc, const char * argv[])
{
// how much memory float consumes

printf("a float consumes %zu bytes\n\n", sizeof(float));

// what is the smallest number a short can hold and its largest

short x;
short y;

for (x; x > -1; x++) {
    continue;
}

for (y; y < 1; y--) {
    continue;
}

printf("\nSmallest short %d\nlargest short %d\n", x, y);

// same question but unsigned short instead

unsigned short i;

for (i; i < 1; i--) {
    continue;
}
printf("largest unsigned short is %d\n", i);

return 0;
}

2 个答案:

答案 0 :(得分:4)

您没有初始化xyi,因此它们不存储连贯的值,而且在表达式中使用它们是无意义的。编译器检测到这种情况,称为未定义的行为,并将表达式标记为未使用的,因为它们是无用的

第一个修复是初始化变量。

short x = 0;
short y = 0;

第二个问题是条件仍然是无稽之谈,即使你从零开始。

for (x; x > -1; x++) { // Keep adding one as long as the result is positive.
// But one plus any positive number is always positive.

for (y; y < 1; y--) { // Keep subtracting one as long as the result is negative.
// But any negative number minus one is always negative.

该程序基于一个常见的误解,即当加法生成一个进位到符号位时,整数类型从最大值到最小值回绕。虽然这在实践中经常发生,但它被归类为未定义的行为,通常被认为是计算故障,而不是特征。如其手册所述,特定编译器可以保证环绕 。 C ++甚至提供了一种检查方法,即std::numeric_limits::is_modulo。然而,Clang和大多数其他现代编译器选择假设,为了静态分析的目的,不会发生溢出,并且正数的添加仅产生正数。引导编译器做出错误的假设可能会导致它产生错误的可执行文件。这可能是警告信息的第二个独立原因。

(无符号类型执行总是从最大值回绕到零。第三个循环应该可以工作,虽然你实际上不需要循环但是(unsigned short) -1会这样做特技。)

要清楚地找到shortunsigned short的限制,请使用:

#include <limits.h>

short smin = SHRT_MIN, smax = SHRT_MAX;
unsigned short usmax = USHRT_MAX;

答案 1 :(得分:1)

Potatoswatter说的是正确的,直接的问题是xyi没有被初始化,所以编译器可以跳过循环或使用任何垃圾发生在运行时的那些寄存器中。

但是,即使它们被正确初始化,在C和C ++中,有符号整数溢出的行为未定义,因此循环可能按预期运行(环绕到符号翻转)或不,或者编译器可以选择完全忽略它们。

不要依赖签名整数。这是龙。