0

嘿,我只是想知道这些警告中的任何一个是否会导致 .exe 在启动时崩溃。以下是警告:

Warning 1   warning C4244: '=' : conversion from 'double' to 'int', possible loss of data   c:\users\conor\documents\college\dkit - year 2 - repeat\dkit - year 2 - semester 1 - repeat\games programming\maroonedca2\maroonedca2\stats.cpp 54  1   MaroonedCA2
Warning 2   warning C4244: 'argument' : conversion from 'time_t' to 'unsigned int', possible loss of data   c:\users\conor\documents\college\dkit - year 2 - repeat\dkit - year 2 - semester 1 - repeat\games programming\maroonedca2\maroonedca2\player.cpp    75  1   MaroonedCA2
Warning 3   warning C4244: 'argument' : conversion from 'time_t' to 'unsigned int', possible loss of data   c:\users\conor\documents\college\dkit - year 2 - repeat\dkit - year 2 - semester 1 - repeat\games programming\maroonedca2\maroonedca2\player.cpp    92  1   MaroonedCA2
Warning 4   warning C4018: '<' : signed/unsigned mismatch   c:\users\conor\documents\college\dkit - year 2 - repeat\dkit - year 2 - semester 1 - repeat\games programming\maroonedca2\maroonedca2\inventory.cpp 63  1   MaroonedCA2

1

int stats[SIZE];
    stats[0] = Status.health;
    stats[1] = Status.strength;
    stats[2] = Status.hitpoints;
    stats[3] = Status.armour;
    stats[4] = Status.luck;

运气是双重的,没有被铸造。

2

 int Player :: hitPoints()
    {
        srand(time(0)); // seed random number generator based on current time
        int randomNumber= rand(); // generate random number
        int hitPoints = (randomNumber% 15) + 1; // get a number between 1 and 20
        return hitPoints;
    }

3

int Player :: fatigue()
{
    srand(time(0)); // seed random number generator based on current time
    int randomNumber= rand(); // generate random number
    int fatigue = (randomNumber% 5) + 1; // get a number between 1 and 5
    return fatigue;
}

4

for (int i= 0; i< inventory.size(); ++i)
        cout<< inventory[i] << endl;
    }
    cout << "\n-----------------------------------------\n";
4

4 回答 4

2

我能看到的唯一一个真正有可能导致崩溃的将是最后一个。如果inventory.size() > INT_MAX,那么在一个典型的实现中,你最终会从一个负索引中读取。

假设您的程序实际上在启动过程中崩溃了,但如果这是问题的根源,我会感到相当惊讶。这更像是一种理论上的可能性,而不是可能的问题来源。首先,在启动时,我猜inventory.size() 可能是0,所以不会发生溢出。其次,我猜你只显示库存以响应命令,而不是在启动期间 - 所以这段代码可能不会在启动期间执行。

其他人有问题,但根本没有可能导致崩溃的问题。

例如,您的示例 #2 和 #3 使用不正确 - 大多数正常程序,几乎srand可以肯定包括这个,应该在程序启动时只调用一次,并且永远不会再次调用它这将导致您的“随机”数字比应有的更可预测,但不会崩溃。srand

于 2012-12-09T13:25:21.287 回答
1

单独来看,这些警告都不会导致崩溃。但是,它们可能会导致其他函数被错误地调用,这些函数对意外值的响应不佳。

您应该获得崩溃的堆栈跟踪,以了解它发生的原因。调试是一个单独的主题,您可以通过 Google 获得大量信息 :)

于 2012-12-09T13:22:31.977 回答
1

你的程序会崩溃吗?

好吧,通常这些警告不会引起太多问题,除非例如您错过了程序中的一些特殊情况,例如将 double 转换为 int 但不检查此 int 是否变为 0 并且除以 0。

让我们来看看所有的警告:

Warning 1   warning C4244: '=' : conversion from 'double' to 'int', possible loss of data

很明显, int 不能存储 double 的所有值,但只要记住它可能已成为可能导致问题的值(如转换为 0),转换它就没有错,但这取决于你用你的 int 做什么。尝试int toint = static_cast<int>(yourdouble);不应该发出警告。

Warning 2   warning C4244: 'argument' : conversion from 'time_t' to 'unsigned int', possible loss of data

time_t 通常有 8 个字节,uint 只有 4 个,所以显然它不能在里面存储所有信息。当您期望一个值但您得到一个不同的值时,数据丢失可能会导致混乱。

Warning 4   warning C4018: '<' : signed/unsigned mismatch

再次没有问题。它只是告诉您,一方面可能是负值,另一方面是不可能的,或者一侧的最大值高于另一侧的最大值。非常常见的警告,通常是由于程序员在只需要无符号时将整数定义为无符号的懒惰而发生的。

编辑:我假设您使用的是 VC。这是一个关于如何忽略警告的示例,如果您确定无法摆脱它们并且可以完全安全地忽略它们(我强烈建议使用 once 参数):

http://msdn.microsoft.com/en-us/library/2c8f766e(v=vs.80).aspx

于 2012-12-09T13:28:16.710 回答
1

每个警告都表明有些事情不太正确。这可能会影响其他代码。


在 …

int stats[SIZE];
stats[0] = Status.health;
stats[1] = Status.strength;
stats[2] = Status.hitpoints;
stats[3] = Status.armour;
stats[4] = Status.luck;

使用Status.luckof type double,您要么丢失信息,要么使用过于通用的类型。信息丢失可能会导致以后崩溃。过于笼统的类型可能会导致其他地方出现错误。

修复取决于这两种可能性中的哪一种。


int Player :: hitPoints()
{
    srand(time(0)); // seed random number generator based on current time
    int randomNumber= rand(); // generate random number
    int hitPoints = (randomNumber% 15) + 1; // get a number between 1 and 20
    return hitPoints;
}

你依赖于从类型time(0)到参数类型的隐式转换srand

time作为游戏的熵源可能是可以的(但对于重复调用的掷骰子程序则不行)。但一定要static_cast在这里使用。到记录的形式参数类型。


int Player :: fatigue()
{
    srand(time(0)); // seed random number generator based on current time
    int randomNumber= rand(); // generate random number
    int fatigue = (randomNumber% 5) + 1; // get a number between 1 and 5
    return fatigue;
}

您正在重新初始化随机数生成器。这很可能是一个错误。我无法想象您希望每次玩家感到疲劳时都重复相同的行为。


for (int i= 0; i< inventory.size(); ++i)
    cout<< inventory[i] << endl;
    }
cout << "\n-----------------------------------------\n";

您缺少一些大括号或大括号,和/或缩进问题。不幸的是它编译了。但修复它。

符号/无符号不匹配是关于有符号i与无符号size_t的比较inventory.size()。在某些情况下,这可能会导致令人讨厌的错误。例如,表达式

string( "hello" ).size() < -3

true由于隐式提升为无符号类型,将始终为,-3并带有环绕。这是非常愚蠢的。非常值得关注。

循环的最佳解决方法是使用size将大小值转换为有符号的函数,例如

typedef ptrdiff_t Size;

template< class Item >
Size size( std::vector<Item> const& v ) { return v.size(); }

然后

for (int i= 0; i < size( inventory ); ++i)
{
    cout<< inventory[i] << endl;
}

这集中了解决方案,以便它适用于所有未来的代码。

将循环控制变量更改为无符号类型只会将问题(特别是隐式转换问题)推到另一个地方。请注意,通常您不会收到有关此类隐式转换的任何警告。大多数编译器只对直接比较发出警告。

对于更通用的size功能,您可以将其定义为

template< class Container >
Size size( Container const& c ) { return end( c ) - begin( c ); }

哪里beginend<utility>头文件中的 C++11 函数。

于 2012-12-09T13:38:54.797 回答