pbootcms网站模板|日韩1区2区|织梦模板||网站源码|日韩1区2区|jquery建站特效-html5模板网

優化掉一個“while(1);"在 C++0x

Optimizing away a quot;while(1);quot; in C++0x(優化掉一個“while(1);在 C++0x)
本文介紹了優化掉一個“while(1);"在 C++0x的處理方法,對大家解決問題具有一定的參考價值,需要的朋友們下面隨著小編來一起學習吧!

問題描述

已更新,見下文!

我聽說并讀到 C++0x 允許編譯器為以下代碼段打印Hello"

I have heard and read that C++0x allows an compiler to print "Hello" for the following snippet

#include <iostream>

int main() {
  while(1) 
    ;
  std::cout << "Hello" << std::endl;
}

它顯然與線程和優化能力有關.不過在我看來,這會讓很多人感到驚訝.

It apparently has something to do with threads and optimization capabilities. It looks to me that this can surprise many people though.

有人對為什么有必要允許這樣做有很好的解釋嗎?作為參考,最新的 C++0x 草案在 6.5/5

Does someone have a good explanation of why this was necessary to allow? For reference, the most recent C++0x draft says at 6.5/5

一個循環,在 for 語句的情況下,在 for-init-statement 之外,

A loop that, outside of the for-init-statement in the case of a for statement,

  • 不調用庫 I/O 函數,并且
  • 不訪問或修改易失性對象,并且
  • 不執行同步操作 (1.10) 或原子操作(第 29 條)

可能由實現假設終止.[注意:這是為了允許編譯器轉換即使無法證明終止,也可以刪除空循環.— 尾注 ]

may be assumed by the implementation to terminate. [ Note: This is intended to allow compiler transfor- mations, such as removal of empty loops, even when termination cannot be proven. — end note ]

這篇富有洞察力的文章介紹了該標準文本

不幸的是,沒有使用未定義行為"這個詞.然而,每當標準說編譯器可以假設 P"時,就暗示具有非 P 屬性的程序具有未定義的語義.

Unfortunately, the words "undefined behavior" are not used. However, anytime the standard says "the compiler may assume P," it is implied that a program which has the property not-P has undefined semantics.

是否正確,是否允許編譯器為上述程序打印Bye"?

Is that correct, and is the compiler allowed to print "Bye" for the above program?

這里有一個更有見地的線程,這是對 C 的類似更改,由 Guy 開始,完成了上面鏈接的文章.在其他有用的事實中,他們提出了一個似乎也適用于 C++0x 的解決方案(更新:這將不再適用于 n3225 - 見下文!)

There is an even more insightful thread here, which is about an analogous change to C, started off by the Guy done the above linked article. Among other useful facts, they present a solution that seems to also apply to C++0x (Update: This won't work anymore with n3225 - see below!)

endless:
  goto endless;

似乎不允許編譯器將其優化掉,因為它不是循環,而是跳轉.另一個人總結了 C++0x 和 C201X 中提議的更改

A compiler is not allowed to optimize that away, it seems, because it's not a loop, but a jump. Another guy summarizes the proposed change in C++0x and C201X

通過編寫一個循環,程序員斷言要么循環執行一些可見行為(執行 I/O,訪問volatile 對象,或執行同步或原子操作),它最終終止.如果我違反了那個假設通過編寫一個沒有副作用的無限循環,我在撒謊編譯器,我的程序的行為是未定義的.(如果我幸運的話,編譯器可能會警告我.)該語言不提供(不再提供?)一種表達無限循環的方法,而無需可見的行為.

By writing a loop, the programmer is asserting either that the loop does something with visible behavior (performs I/O, accesses volatile objects, or performs synchronization or atomic operations), or that it eventually terminates. If I violate that assumption by writing an infinite loop with no side effects, I am lying to the compiler, and my program's behavior is undefined. (If I'm lucky, the compiler might warn me about it.) The language doesn't provide (no longer provides?) a way to express an infinite loop without visible behavior.

<小時>

2011 年 1 月 3 日更新 n3225:委員會將文本移至 1.10/24 并說


Update on 3.1.2011 with n3225: Committee moved the text to 1.10/24 and say

該實現可能假設任何線程最終都會執行以下操作之一:

The implementation may assume that any thread will eventually do one of the following:

  • 終止,
  • 調用庫 I/O 函數,
  • 訪問或修改易失性對象,或
  • 執行同步操作或原子操作.

goto 技巧將不再工作!

推薦答案

有人對為什么有必要允許這樣做有很好的解釋嗎?

Does someone have a good explanation of why this was necessary to allow?

是的,Hans Boehm 在N1528:為什么無限循環的未定義行為?,雖然這是 WG14 文檔,但基本原理也適用于 C++,該文檔同時引用了 WG14 和 WG21:

Yes, Hans Boehm provides a rationale for this in N1528: Why undefined behavior for infinite loops?, although this is WG14 document the rationale applies to C++ as well and the document refers to both WG14 and WG21:

正如 N1509 正確指出的那樣,目前的草案基本上給出了6.8.5p6 中無限循環的未定義行為.一個主要問題這樣做是為了允許代碼在一個潛在的非終止循環.例如,假設我們有以下循環,其中 count 和 count2 是全局變量(或有它們的地址取),而p是局部變量,地址未被取:

As N1509 correctly points out, the current draft essentially gives undefined behavior to infinite loops in 6.8.5p6. A major issue for doing so is that it allows code to move across a potentially non-terminating loop. For example, assume we have the following loops, where count and count2 are global variables (or have had their address taken), and p is a local variable, whose address has not been taken:

for (p = q; p != 0; p = p -> next) {
    ++count;
}
for (p = q; p != 0; p = p -> next) {
    ++count2;
}

可以將這兩個循環合并并替換為以下循環嗎?

Could these two loops be merged and replaced by the following loop?

for (p = q; p != 0; p = p -> next) {
        ++count;
        ++count2;
}

沒有 6.8.5p6 中對無限循環的特殊規定,這將被禁止:如果第一個循環沒有終止,因為 q指向一個循環列表,原來從不寫入count2.因此它可以與另一個訪問或訪問的線程并行運行更新計數2.轉換后的版本不再安全盡管存在無限循環,但它確實訪問了 count2 .就這樣轉換可能會引入數據競爭.

Without the special dispensation in 6.8.5p6 for infinite loops, this would be disallowed: If the first loop doesn't terminate because q points to a circular list, the original never writes to count2. Thus it could be run in parallel with another thread that accesses or updates count2. This is no longer safe with the transformed version which does access count2 in spite of the infinite loop. Thus the transformation potentially introduces a data race.

在這種情況下,編譯器不太可能能夠證明循環終止;它必須明白 q 點到一個非循環列表,我認為這超出了大多數人的能力主流編譯器,如果沒有整個程序,通常是不可能的信息.

In cases like this, it is very unlikely that a compiler would be able to prove loop termination; it would have to understand that q points to an acyclic list, which I believe is beyond the ability of most mainstream compilers, and often impossible without whole program information.

非終止循環施加的限制是對編譯器無法執行的終止循環的優化證明終止,以及實際的優化非終止循環.前者比后者更常見后者,通常更有趣的是優化.

The restrictions imposed by non-terminating loops are a restriction on the optimization of terminating loops for which the compiler cannot prove termination, as well as on the optimization of actually non-terminating loops. The former are much more common than the latter, and often more interesting to optimize.

顯然也有帶有整數循環變量的 for 循環編譯器很難證明終止,并且因此編譯器很難重構循環沒有 6.8.5p6.甚至像

There are clearly also for-loops with an integer loop variable in which it would be difficult for a compiler to prove termination, and it would thus be difficult for the compiler to restructure loops without 6.8.5p6. Even something like

for (i = 1; i != 15; i += 2)

for (i = 1; i <= 10; i += j)

處理起來似乎很重要.(在前一種情況下,一些基本數字需要理論來證明終止,在后一種情況下,我們需要了解有關 j 的可能值的一些信息.環繞式對于無符號整數可能會使某些推理進一步復雜化.)

seems nontrivial to handle. (In the former case, some basic number theory is required to prove termination, in the latter case, we need to know something about the possible values of j to do so. Wrap-around for unsigned integers may complicate some of this reasoning further.)

這個問題似乎適用于幾乎所有的循環重組轉換,包括編譯器并行化和緩存優化轉換,這兩者都有可能獲得的重要性,并且對于數字代碼已經很重要了.這似乎可能會轉化為巨大的成本能夠以最自然的方式編寫無限循環,尤其是因為我們大多數人很少故意編寫無限循環.

This issue seems to apply to almost all loop restructuring transformations, including compiler parallelization and cache-optimization transformations, both of which are likely to gain in importance, and are already often important for numerical code. This appears likely to turn into a substantial cost for the benefit of being able to write infinite loops in the most natural way possible, especially since most of us rarely write intentionally infinite loops.

與 C 的一個主要區別是 C11 為控制常量表達式的表達式提供了一個例外,這與 C++ 不同并使您的具體示例在 C11 中得到明確定義.

The one major difference with C is that C11 provides an exception for controlling expressions that are constant expressions which differs from C++ and makes your specific example well-defined in C11.

這篇關于優化掉一個“while(1);"在 C++0x的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!

【網站聲明】本站部分內容來源于互聯網,旨在幫助大家更快的解決問題,如果有圖片或者內容侵犯了您的權益,請聯系我們刪除處理,感謝您的支持!

相關文檔推薦

Algorithm to convert RGB to HSV and HSV to RGB in range 0-255 for both(將 RGB 轉換為 HSV 并將 HSV 轉換為 RGB 的算法,范圍為 0-255)
How to convert an enum type variable to a string?(如何將枚舉類型變量轉換為字符串?)
When to use inline function and when not to use it?(什么時候使用內聯函數,什么時候不使用?)
Examples of good gotos in C or C++(C 或 C++ 中好的 goto 示例)
Significance of ios_base::sync_with_stdio(false); cin.tie(NULL);(ios_base::sync_with_stdio(false) 的意義;cin.tie(NULL);)
Is TCHAR still relevant?(TCHAR 仍然相關嗎?)
主站蜘蛛池模板: 美国PARKER齿轮泵,美国PARKER柱塞泵,美国PARKER叶片泵,美国PARKER电磁阀,美国PARKER比例阀-上海维特锐实业发展有限公司二部 | 红立方品牌应急包/急救包加盟,小成本好项目代理_应急/消防/户外用品加盟_应急好项目加盟_新奇特项目招商 - 中红方宁(北京) 供应链有限公司 | 昆山PCB加工_SMT贴片_PCB抄板_线路板焊接加工-昆山腾宸电子科技有限公司 | BHK汞灯-百科|上海熙浩实业有限公司| 定硫仪,量热仪,工业分析仪,马弗炉,煤炭化验设备厂家,煤质化验仪器,焦炭化验设备鹤壁大德煤质工业分析仪,氟氯测定仪 | 济宁工业提升门|济宁电动防火门|济宁快速堆积门-济宁市统一电动门有限公司 | 交联度测试仪-湿漏电流测试仪-双85恒温恒湿试验箱-常州市科迈实验仪器有限公司 | 展厅设计公司,展厅公司,展厅设计,展厅施工,展厅装修,企业展厅,展馆设计公司-深圳广州展厅设计公司 | 盛源真空泵|空压机-浙江盛源空压机制造有限公司-【盛源官网】 | 锻造液压机,粉末冶金,拉伸,坩埚成型液压机定制生产厂家-山东威力重工官方网站 | 书法培训-高考书法艺考培训班-山东艺霖书法培训凭实力挺进央美 | 板框压滤机-隔膜压滤机配件生产厂家-陕西华星佳洋装备制造有限公司 | 精密交叉滚子轴承厂家,转盘轴承,YRT转台轴承-洛阳千协轴承 | 酒糟烘干机-豆渣烘干机-薯渣烘干机-糟渣烘干设备厂家-焦作市真节能环保设备科技有限公司 | 三价铬_环保铬_环保电镀_东莞共盈新材料贸易有限公司 | 天津市能谱科技有限公司-专业的红外光谱仪_红外测油仪_紫外测油仪_红外制样附件_傅里叶红外光谱技术生产服务厂商 | 医疗仪器模块 健康一体机 多参数监护仪 智慧医疗仪器方案定制 血氧监护 心电监护 -朗锐慧康 | 金属清洗剂,防锈油,切削液,磨削液-青岛朗力防锈材料有限公司 | 耐酸泵,耐腐蚀真空泵,耐酸真空泵-淄博华舜耐腐蚀真空泵有限公司 精密模具-双色注塑模具加工-深圳铭洋宇通 | 无硅导热垫片-碳纤维导热垫片-导热相变材料厂家-东莞市盛元新材料科技有限公司 | 地图标注|微信高德百度地图标注|地图标记-做地图[ZuoMap.com] | 金环宇|金环宇电线|金环宇电缆|金环宇电线电缆|深圳市金环宇电线电缆有限公司|金环宇电缆集团 | 优秀的临床医学知识库,临床知识库,医疗知识库,满足电子病历四级要求,免费试用 | 发电机价格|发电机组价格|柴油发电机价格|柴油发电机组价格网 | 塑料瓶罐_食品塑料瓶_保健品塑料瓶_调味品塑料瓶–东莞市富慷塑料制品有限公司 | 压力控制器,差压控制器,温度控制器,防爆压力控制器,防爆温度控制器,防爆差压控制器-常州天利智能控制股份有限公司 | 喷播机厂家_二手喷播机租赁_水泥浆洒布机-河南青山绿水机电设备有限公司 | 工作心得_读书心得_学习心得_找心得体会范文就上学道文库 | 北京中创汇安科贸有限公司| 绿叶|绿叶投资|健康产业_绿叶投资集团有限公司 | 深圳市简易检测技术有限公司| 圆形振动筛_圆筛_旋振筛_三次元振动筛-河南新乡德诚生产厂家 | 汝成内控-行政事业单位内部控制管理服务商 | 济南菜鸟驿站广告|青岛快递车车体|社区媒体-抖音|墙体广告-山东揽胜广告传媒有限公司 | 科威信洗净科技,碳氢清洗机,超声波清洗机,真空碳氢清洗机 | app开发|app开发公司|小程序开发|物联网开发||北京网站制作|--前潮网络 | 集菌仪厂家_全封闭_封闭式_智能智能集菌仪厂家-上海郓曹 | 工业车间焊接-整体|集中除尘设备-激光|等离子切割机配套除尘-粉尘烟尘净化治理厂家-山东美蓝环保科技有限公司 | 广州各区危化证办理_危险化学品经营许可证代办 | 加热制冷恒温循环器-加热制冷循环油浴-杭州庚雨仪器有限公司 | 青岛球场围网,青岛车间隔离网,青岛机器人围栏,青岛水源地围网,青岛围网,青岛隔离栅-青岛晟腾金属制品有限公司 |