我知道未初始化的局部变量是未定义的行为(UB),并且该值可能具有可能影响进一步操作的陷阱表示,但有时我想仅使用随机数进行可视化表示,并且不会在其他部分使用它们.例如,程序在视觉效果中设置具有随机颜色的东西,例如:
void updateEffect(){
    for(int i=0;i<1000;i++){
        int r;
        int g;
        int b;
        star[i].setColor(r%255,g%255,b%255);
        bool isVisible;
        star[i].setVisible(isVisible);
    }
}
是不是比它快
void updateEffect(){
    for(int i=0;i<1000;i++){
        star[i].setColor(rand()%255,rand()%255,rand()%255);
        star[i].setVisible(rand()%2==0?true:false);
    }
}
并且还比其他随机数发生器更快?
我正在尝试制作一个与不同的崩溃过程接口的Python程序(这不在我的手中).不幸的是,我正在连接的程序甚至没有可靠的崩溃!所以我想制作一个快速崩溃的C++程序,但我实际上并不知道最好和最短的方法,有谁知道我的:
int main() {
    crashyCodeGoesHere();
}
使我的C++程序可靠地崩溃
编辑:这个问题并不是一个讨论未定义行为的(de)优点的论坛,但这就是它的变化.在任何情况下,这个关于假设的C编译器没有未定义行为的线程可能对那些认为这是一个重要主题的人更感兴趣.
当然,"未定义行为"的经典伪装例子是"鼻子恶魔" - 物理上是不可能的,无论C和C++标准允许什么.
因为C和C++社区倾向于强调未定义行为的不可预测性以及允许编译器在遇到未定义行为时使程序完全做任何事情的想法,所以我假设标准没有任何限制关于行为,以及未定义的行为.
[C++14: defns.undefined]:[..]允许的未定义行为包括完全忽略不可预测的结果,在转换或程序执行期间以环境特征(有或没有发出诊断消息)的文档方式执行,终止转换或执行(发布诊断信息).[..]
这实际上指定了一小组可能的选项:
我假设在大多数情况下,编译器选择忽略未定义的行为; 例如,当读取未初始化的内存时,可能是插入任何代码以确保一致行为的反优化.我认为陌生人类型的未定义行为(例如" 时间旅行 ")将属于第二类 - 但这需要记录这些行为并"环境特征"(所以我猜鼻腔恶魔只能由地狱计算机?).
我误解了这个定义吗?这些仅仅是可能构成未定义行为的例子,而不是一个全面的选项列表吗?"任何可能发生的事情"的说法仅仅意味着忽视这种情况的意外副作用吗?
编辑:两个小问题澄清:
我有以下代码:
#include <iostream>
#include <complex>
using namespace std;
int main() {
    complex<int> delta;
    complex<int> mc[4] = {0};
    for(int di = 0; di < 4; di++, delta = mc[di]) {
        cout << di << endl;
    }
    return 0;
}
我希望它输出"0,1,2,3"并停止,但它会输出一系列无穷无尽的"0,1,2,3,4,5 ......"
看起来比较di<4效果不好并且总是返回true.
如果我只是评论出来,delta=mc[di],我会像往常一样得到"0,1,2,3".无辜任务有什么问题?
我正在使用带有-O2选项的Ideone.com g ++ C++ 14.
我更喜欢编写可靠的shell代码,因此总是设置errexit和nounset.
以下代码将在bad_command行停止
#!/bin/bash
set -o errexit ; set -o nounset
bad_command # stop here
good_command
我想抓住它,这是我的方法
#!/bin/bash
set -o errexit ; set -o nounset
rc=1
bad_command && rc=0 # stop here
[ $rc -ne 0 ] && do_err_handle
good_command
有没有更好或更清洁的方法
我的答案:
#!/bin/bash
set -o errexit ; set -o nounset
if ! bad_command ; then
  # error handle here
fi
good_command
在下面的代码中,*(long*)0=0;与if子句一起使用,但它的目的是什么?
if(r.wid*r.ht < tot)
    *(long*)0=0;
我想知道对一段 C 代码进行可靠的分段错误的最佳方法是什么?
我完全意识到这是不好的行为,永远不应该用在一个软件中,但我想知道我如何能够持续地强制它发生。
编辑:我得到的答案不是我最初想要的,但对于理解为什么这个问题没有可靠答案很有价值。
我在阅读redis源代码时遇到问题,有人能告诉我debug.c中_redisAssert函数中最后一个语句的用法是什么:
*((char*)-1) = 'x';
这是一个疯狂的黑客,但我试图故意在执行的特定点导致段错误,所以valgrind将给我一个堆栈跟踪.
如果有更好的方法,请告诉我,但我仍然很想知道如何故意导致段错误,以及为什么我的尝试不起作用.
这是我失败的尝试:
long* ptr = (long *)0xF0000000;
ptr = 10;
我认为valgrind至少应该把它作为一个无效的写入,即使它不是一个分段违规.Valgrind对此一无所知.
有什么想法吗?
编辑
接受了答案,但我仍然有一些上升的选票,以获得一个更理智的方式来获得堆栈跟踪...
这个例子:
#include <optional>
#include <iostream>
using namespace std;
int main()
{
    optional<int> t{}; // nullopt (empty) by default
    cout << *t << endl;
    return 0;
}
实际上这个程序打印一些int(未初始化的类型值int).此外,libcxx使用assert-check来访问非参与值.
为什么标准不要求扔或sigsegv在这里?
我正在尝试设置我的服务器处理核心转储的方式.为了测试它,我需要一个总是段错误的程序.
是否有一个简单的示例程序总是会出现段错误?