C和C++中未定义,未指定和实现定义的行为有什么区别?
c c++ undefined-behavior unspecified-behavior implementation-defined-behavior
访问其边界之外的数组有多危险(在C中)?有时候我会从数组外部读取(我现在理解我然后访问我的程序的某些其他部分使用的内存,甚至超过它)或者我试图将值设置为数组之外的索引.该程序有时会崩溃,但有时只是运行,只会产生意想不到的结果.
现在我想知道的是,这真的有多危险?如果它损坏我的程序,那就不是那么糟糕了.另一方面,如果它打破了我的程序之外的东西,因为我以某种方式设法访问一些完全不相关的内存,那么它是非常糟糕的,我想.我读了很多"任何可能发生的事情","分割可能是最不好的问题","你的硬盘可能会变成粉红色,独角兽可能会在你的窗下唱歌",这很好,但真正的危险是什么?
我的问题:
我使用OSX 10.7,Xcode 4.6.
诚然,我不明白.假设您的内存中包含长度为1个字节的内存字.为什么不能在未对齐地址的单个内存访问中访问一个4字节长的变量(即不能被4整除),因为对齐地址就是这种情况?
如果我有:
unsigned int x;
x -= x;
Run Code Online (Sandbox Code Playgroud)
很明显,x 应该这样表达后是零,但到处看,他们说的行为,这种代码是不确定的,而不是仅仅值x(直到减法之前).
两个问题:
这段代码的行为确实未定义吗?
(例如,代码在兼容系统上崩溃[或更糟]?)
如果是这样,为什么 C表示行为是未定义的,当非常清楚x这里应该为零时?
即不在此定义行为给出的优势是什么?
很明显,编译器可以简单地使用它在变量中认为"方便"的任何垃圾值,并且它可以按预期工作......这种方法有什么问题?
我今天刚上课了 - 阅读C代码和输入,如果程序实际运行,所需答案就是屏幕上显示的内容.其中一个问题被声明a[4][4]为一个全局变量,并且在该程序的一个点上,它试图访问a[27][27],所以我回答了类似" 访问一个超出其边界的数组是一个未定义的行为 ",但老师说它a[27][27]的值将为0.
之后,我尝试了一些代码来检查"所有未初始化的golbal变量是否设置为0"是否为真.好吧,这似乎是真的.
所以现在我的问题是:
a[27][27]是0所有环境?编辑:
在该代码中,a[4][4]是唯一声明的全局变量,并且还有一些更多本地变量main().
我在DevC++中再次尝试了该代码.所有这些都是0.但在VSE中并非如此,其中大多数值都是,0但有些值具有Vyktor指出的随机值.
将指针转换为int并稍后再返回指针是否安全?
如果我们知道指针是否为32位长且int是32位长怎么样?
long* juggle(long* p) {
static_assert(sizeof(long*) == sizeof(int));
int v = reinterpret_cast<int>(p); // or if sizeof(*)==8 choose long here
do_some_math(v); // prevent compiler from optimizing
return reinterpret_cast<long*>(v);
}
int main() {
long* stuff = new long(42);
long* ffuts = juggle(stuff);
std::cout << "Is this always 42? " << *ffuts << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
这是否包含在标准中?
int data[8];
data[9] = 1;
Run Code Online (Sandbox Code Playgroud)
c ++标准对此有何评论?这是未定义的行为吗?
至少C编译器(gcc -std = c99 -pedantic -W -Wall)对此没有任何说明.
谢谢.