嘿,我只是想知道这些警告会导致.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";
答案 0 :(得分:2)
我认为其中唯一可能导致崩溃的可能性是最后一次。如果是inventory.size() > INT_MAX
,那么在典型的实现中,您最终将从负面索引中读取。
假设你的程序在启动过程中确实崩溃了,如果这是问题的根源,我会感到很惊讶。它更像是理论上的可能性,而不是可能的问题来源。首先,在启动时,我猜测inventory.size()可能为0,因此不会发生溢出。其次,我猜你只显示库存以响应命令,而不是在启动期间 - 所以这段代码可能在启动时不执行。
其他人有问题,但不是那些可能导致崩溃的问题。
例如,您的示例#2和#3错误地使用了srand
- 大多数正常程序,几乎肯定包括这个程序,应该完全一次调用srand
程序启动时,再也不会调用它。这将导致你的“随机”数字比它们应该更容易预测,但不会崩溃。
答案 1 :(得分:1)
孤立地说,这些警告都不会导致崩溃。但是,它们可能会导致其他函数被错误地调用,而这些函数对意外值的反应不会很好。
您应该获得崩溃的堆栈跟踪,以了解它发生的原因。调试是一个单独的主题,您可以通过Google获得大量信息:)
答案 2 :(得分: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。以下是一个关于如何忽略警告的示例IFF您确定无法摆脱它们并且它们完全可以忽略(我强烈建议使用once参数):
http://msdn.microsoft.com/en-us/library/2c8f766e(v=vs.80).aspx
答案 3 :(得分: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.luck
类型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
函数将size值转换为signed,例如
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 ); }
其中begin
和end
是<utility>
标题中的C ++ 11函数。