根据这个SO答案,int在C中递增未初始化会导致未定义的行为.但是,如果我根本不在乎初始价值呢?例如,如果我只想要递增ID怎么办?这是出于任何原因的危险或不良做法吗?
如果访问具有自动存储持续时间的对象的值,并且该对象未初始化,则行为未定义.在N1570 6.3.2.1第2段(这是ISO C标准的最新公开草案)中明确和正式地陈述了这一点.
" 未定义的行为 "并不仅仅意味着您可能获得任意值.它表示"使用不可移植或错误的程序结构或错误数据时的行为,本国际标准不对其施加任何要求"(N1570 3.4.3).语言标准几乎没有说明访问这样一个对象的价值意味着什么.这实际上是纯粹的胡言乱语.(标准的笑话是,未定义的行为会导致恶魔飞出你的鼻子.当然,在现实生活中它不能 - 但如果它确实你不能抱怨编译器是不符合的.)
但是让我们暂时忽略访问未初始化的未定义行为int.也许你今天感觉很幸运.也许你知道你的编译器将如何处理这种情况.
更确切地说,让我们对这种未定义的行为如何表现出一些合理的假设.
假设我们有:
int i;
i ++;
Run Code Online (Sandbox Code Playgroud)
假设(未定义的)初始值i恰好是INT_MAX.然后递增i会导致有符号整数溢出,这也是明确未定义的行为(N1570 6.5第5段).即使初始值小于INT_MAX,增加足够的次数也会导致溢出 - 而且由于您不知道初始值是什么,因此您不知道可以"安全"增加它的次数.
最可能的坏结果是优化编译器将以依赖于其行为定义的假设的方式转换代码.这是一个不涉及未初始化变量的示例:
int i = INT_MAX;
int j = i + 1;
if (j > i) { /* ... */ }
Run Code Online (Sandbox Code Playgroud)
如果add遵循常见的环绕式2的补码语义(C标准无法保证,但通常是硬件中实现的),那么j它将等于INT_MIN,并且(j > i)将为false.逻辑上,(j > i) 必须是假的,因为没有int价值可以超过INT_MAX.但是既然j设置为i + 1,则(j > i) 必须为真(对于任何已定义行为的程序).
无论您对此代码的行为有何期望,优化编译器都可能在法律上违反它们.如果你很幸运,可能会在破坏你的代码之前警告你,但不是必须的.
你花费的时间远远少于我们花在讨论如果你不这样做会发生什么= 0的声明i.(但即便如此,如果增加i足够的次数导致溢出,也可能会遇到问题.)
当大多数人读到"这会导致未定义的行为"时,他们最初会将其解释为"你感兴趣的变量的价值是不确定的".
文字的字面意思是什么意思:在行为中的程序本身是不确定的.
如果他们想告诉你一个值是不确定的,那么他们会说这个值是不确定的.但他们没有.这些是具有不同含义的不同句子.
当行为是不确定的,这意味着该计划是毫无意义的 -例如,变量可能甚至不再存在时,在你做出它的价值推理的地步.
该程序甚至可能没有执行您认为的代码.它可能只是跳到其他地方,它可能会突然删除磁盘上的文件,它可以做任何事情.质疑变量的值完全没有意义.
这与您的示例一样糟糕,因为虽然您可能期望它等效i = 0,但它也会导致未定义的行为:
int i;
i -= i;
Run Code Online (Sandbox Code Playgroud)
即,未定义的行为与任何特定变量的值无关.这是关于行为(动词),而不是数据(名词).