- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
根据“未定义行为”的现代解释,编译器有权假设不会发生导致未定义行为“不可避免”的事件链,并且可以消除仅适用于以下情况的代码:将执行未定义的行为;这可能会导致未定义行为的影响及时倒退,并使原本可以观察到的行为无效。另一方面,如果除非程序终止,否则未定义行为将不可避免,但程序可以并且确实在调用未定义行为之前终止,程序的行为将保持完全定义。
在做出这个决定时,编译器需要考虑哪些终止原因?举几个例子:
在许多平台上,对像“getc”这样的函数的调用通常会返回(至少最终),但在某些超出编译器控制的情况下不会返回。如果有这样的程序:
int main(int argc, char *argv[])
{
if (argc != 3)
{
printf("Foo\n");
return 0;
}
else
{
int ch;
printf("You'd better type control-C!\n");
int ch = getc();
if (ch < 65)
return (ch-33) / (argc-3);
else
return INT_MAX + ch;
}
}
如果使用等于 3 的 argc
调用程序,但 SIGINT 阻止 getc()
调用返回,是否会定义行为?当然,如果 getc()
可以返回任何值,这将导致定义的行为,则在编译器可以确定此类输入不会发生之前,不会发生未定义的行为已收到。如果没有值 getc()
可以返回,这将避免未定义的行为,但是,如果 getc()
被阻止返回任何值,整个程序是否会保持定义值(value)? getc()
的返回值与调用未定义行为的操作之间是否存在因果关系会影响事情吗(在上面的示例中,编译器无法知道任何特定 在不知道输入什么字符的情况下会发生未定义行为的形式,但任何可能的输入都会触发某种形式)。
同样,如果在平台上存在地址,如果读取这些地址,则指定会导致程序立即终止,编译器指定 volatile 读取将触发硬件读取请求,并且该平台上的某些外部库指定它会返回指向这样一个地址的指针,这些因素是否意味着 bar
在这个单独的例子中的行为:
int foo(int x)
{
char volatile * p = get_instant_quit_address();
if (x)
{ printf("Hey"); fflush(stdout); }
return *p / x; // Will cause UB if *p yields a value and x is zero
}
int bar(void)
{
return foo(0);
}
如果尝试读取 *p 实际上会立即终止程序执行而不产生值,那么
将被定义(作为终止而没有打印任何东西)?在返回一个值之前,除法不能继续;因此,如果没有返回值,则不会除以零。
允许 C 编译器通过什么方式确定给定的操作是否可能导致程序执行以它不知道的方式终止,以及在什么情况下允许在此类操作之前重新安排未定义的行为?
最佳答案
这在 [intro.execution] 下的 C++ 中有很好的描述:
5 - A conforming implementation executing a well-formed program shall produce the same observable behavior as one of the possible executions of the corresponding instance of the abstract machine with the same program and the same input. However, if any such execution contains an undefined operation, this International Standard places no requirement on the implementation executing that program with that input (not even with regard to operations preceding the first undefined operation).
普遍认为 C 具有相同的特性,因此 C 编译器可以类似地执行 "time travel"存在未定义的行为。
重要的是,请注意问题是是否存在表现出未定义行为的抽象机实例;您可以通过先终止程序执行来安排防止机器上出现未定义的行为,这并不重要。
如果您使程序以抽象机器无法摆脱的完全定义的方式自行终止,您可以防止未定义的行为(以及由此产生的时间旅行)。例如,在您的第二个示例中,如果您将对 *p
的访问替换为 (exit(0), 0)
那么未定义的行为就不会发生,因为不可能执行exit
返回给它的调用者的抽象机。但是无论您的平台有何特点,抽象机都不必在访问 insta-kill 地址时终止您的程序(事实上,抽象机没有任何 insta-kill 地址)。
关于如果 getc() 通过 SIGINT 退出,则 getc() 之后的未定义行为是否可以改变程序行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29855620/
我有以下MWE function f(p) ans = zeros(p, 2) return ans end ans = f(2) ans b=ans.+1.0 ans 起初,ans是正确的,
OWIN AppBuilder“UseStatic”位从本地文件系统传送文件,这在某些情况下很方便,但我希望它从我在应用程序启动时预先填充的内存中 IDictionary 传送内容。任何人都可以指出一
我是 JavaScript 新手。 我的代码允许我列出 JSON 文档的元素及其类型,并将所有元素连接到一个字符串 donnees_types 中。 问题是 JavaScript 中的 typeof
我想在每次刷新时更改主页上的背景图像。我怎样才能做到这一点?我认为 jquery 是可能的,但我不太清楚。 感谢您对此主题的任何帮助或评论。 最佳答案 我不知道“如何”,但我找到了以下链接: http
所以我已经在这上面花了几个小时了,老实说我完全陷入困境。我写了一个 for 循环来计算整数中的数字数量,但我发现一旦我输入 10 位以上的数字,除数值就会发生变化,而且我不明白为什么。我在互联网上搜索
当我在使用表面 View 的游戏 Activity 和使用膨胀菜单的其他 Activity 之间切换时,我会收到错误消息。 日志猫: 07-13 15:15:34.464: ERROR/Android
听说很简单 R*=f; G*=f; B*=f; 其中 f 是标量值 0 .. 1.0 或更大改变亮度的方法不太正确颜色,但我找不到一些代码片段获得更好的东西(无需太多学习色彩理论)也许有人可以在这里给
如以下链接所述:- How to get the ThreadPoolExecutor to increase threads to max before queueing? 我将队列实现更改为在进入
我只显示最初提供 20 分钟 slotMinutes 的日历。我试图让用户即时更改为 10 分钟的 slotMinutes。 我有一个触发以下代码的按钮: $('#calendar').fullCal
我的问题是:我的应用程序中有一个新闻列表(UITableView)当我点击 1 个"new"时,我打开它,里面有一个后退按钮,可以让我回到列表。现在的问题是我必须在滑动时实现"new"更改,所以我制作
我面临着与 I'm trying to install psycopg2 onto Mac OS 10.6.3; it claims it can't find "stdarg.h" but I ca
需要通过为 array2 中不存在的索引设置 visible false 来从 array1 创建一个新的 array3。 在下面的示例中,我有索引 0,2。所以对于 1,3,结果数组必须具有 vis
我有一个对象,类似这样 var Egg = function(){ this.test = $(.slider .label); $('.slider').slider({
我想改变 ScrollView 的宽度。首先,我这样做了: var scrollWidthConstraint: NSLayoutConstraint! 然后设置它: scrollWidthConst
我有两个动画,一个是“过渡”,它在悬停时缩小图像,另一个是 animation2,其中图像的不透明度以周期性间隔重复变化。 我有 animation2 在图像上进行,当我将鼠标悬停在它上面时,anim
我是一个 jQuery 新手,一直在尝试添加一个脚本来更改 div onClick 的 id。 这是一个jsfiddle example . $(function accept() { $("
我正在尝试更改用户输入的字母的大小写,并将该字母的小写和大写版本存储在变量中。我已经编写了下面的代码,但它在运行时遇到了问题。有人指出是什么导致了问题吗? #include #include #i
假设我有这段代码: char num[2] = {15, 240}; char* p_num; 现在,如果我理解的一切正确,数组中的位应该像这样对齐: 00001111 11110000 我的问题是
var html = '' + count + '' + i.Description + '' + i.Priority + '' + i.Status + 'johnsmith- ' + creat
我在虚拟机上安装了 minix3,并希望我可以操纵当前的队列选择算法,以便我可以将其从优先级顺序更改为包括随机分类的低优先级作业的优先级顺序。我发现我需要更改的代码部分在 proc.c 中,具体部分是
我是一名优秀的程序员,十分优秀!