導航:首頁 > 源碼編譯 > 編譯器開啟優化後出現了其他問題

編譯器開啟優化後出現了其他問題

發布時間:2022-06-21 18:55:04

① C#的問題 我感覺是編譯器優化的時候優化出問題來了

第1段代碼,當循環到 i=len-2 時,進行 if 段,這時在 if 段內要求: i++,那麼這時候 i=len-1 了。然後進入下一輪循環,這時因為 i==len-1 就進入 else 部份了。

第2段代碼,同樣,當循環到 i=len-2 時,同樣在 if 段內 i++ 造成 i=len-1,這時再往下走,走到
if(i==len-1) ,判斷就為true,就break了。

② Debug編譯通過,Release編譯報錯,為什麼

對照這些選項看看 Release 版錯誤是怎樣產生的

1. Runtime Library:鏈接哪種運行時刻函數庫通常只對程序的性能產生影響。調試版本的 Runtime Library 包含了調試信息,並採用了一些保護機制以幫助發現錯誤,因此性能不如發布版本。編譯器提供的 Runtime Library 通常很穩定,不會造成 Release 版錯誤;倒是由於 Debug 的 Runtime Library 加強了對錯誤的檢測,如堆內存分配,有時會出現 Debug 有錯但 Release 正常的現象。應當指出的是,如果 Debug 有錯,即使 Release 正常,程序肯定是有 Bug 的,只不過可能是 Release 版的某次運行沒有表現出來而已。

2. 優化:這是造成錯誤的主要原因,因為關閉優化時源程序基本上是直接翻譯的,而打開優化後編譯器會作出一系列假設。這類錯誤主要有以下幾種:

(1) 幀指針(Frame Pointer)省略(簡稱 FPO ):在函數調用過程中,所有調用信息(返回地址、參數)以及自動變數都是放在棧中的。若函數的聲明與實現不同(參數、返回值、調用方式),就會產生錯誤 ————但 Debug 方式下,棧的訪問通過 EBP 寄存器保存的地址實現,如果沒有發生數組越界之類的錯誤(或是越界「不多」),函數通常能正常執行;Release 方式下,優化會省略 EBP 棧基址指針,這樣通過一個全局指針訪問棧就會造成返回地址錯誤是程序崩潰。C++ 的強類型特性能檢查出大多數這樣的錯誤,但如果用了強制類型轉換,就不行了。你可以在 Release 版本中強制加入 /Oy- 編譯選項來關掉幀指針省略,以確定是否此類錯誤。此類錯誤通常有:

● MFC 消息響應函數書寫錯誤。正確的應為
afx_msg LRESULT OnMessageOwn(WPARAM wparam, LPARAM lparam);
ON_MESSAGE 宏包含強制類型轉換。防止這種錯誤的方法之一是重定義 ON_MESSAGE 宏,把下列代碼加到 stdafx.h 中(在#include "afxwin.h"之後),函數原形錯誤時編譯會報錯
#undef ON_MESSAGE
#define ON_MESSAGE(message, memberFxn) \
{ message, 0, 0, 0, AfxSig_lwl, \
(AFX_PMSG)(AFX_PMSGW)(static_cast< LRESULT (AFX_MSG_CALL \
CWnd::*)(WPARAM, LPARAM) > (&memberFxn) },

(2) volatile 型變數:volatile 告訴編譯器該變數可能被程序之外的未知方式修改(如系統、其他進程和線程)。優化程序為了使程序性能提高,常把一些變數放在寄存器中(類似於 register 關鍵字),而其他進程只能對該變數所在的內存進行修改,而寄存器中的值沒變。如果你的程序是多線程的,或者你發現某個變數的值與預期的不符而你確信已正確 的設置了,則很可能遇到這樣的問題。這種錯誤有時會表現為程序在最快優化出錯而最小優化正常。把你認為可疑的變數加上 volatile 試試。

(3) 變數優化:優化程序會根據變數的使用情況優化變數。例如,函數中有一個未被使用的變數,在 Debug 版中它有可能掩蓋一個數組越界,而在 Release 版中,這個變數很可能被優化調,此時數組越界會破壞棧中有用的數據。當然,實際的情況會比這復雜得多。與此有關的錯誤有:
● 非法訪問,包括數組越界、指針錯誤等。例如
void fn(void)
{
int i;
i = 1;
int a[4];
{
int j;
j = 1;
}
a[-1] = 1;//當然錯誤不會這么明顯,例如下標是變數
a[4] = 1;
}
j 雖然在數組越界時已出了作用域,但其空間並未收回,因而 i 和 j 就會掩蓋越界。而 Release 版由於 i、j 並未其很大作用可能會被優化掉,從而使棧被破壞。

3. _DEBUG 與 NDEBUG :當定義了 _DEBUG 時,assert() 函數會被編譯,而 NDEBUG 時不被編譯。除此之外,VC++中還有一系列斷言宏。這包括:

ANSI C 斷言 void assert(int expression );
C Runtime Lib 斷言 _ASSERT( booleanExpression );
_ASSERTE( booleanExpression );
MFC 斷言 ASSERT( booleanExpression );
VERIFY( booleanExpression );
ASSERT_VALID( pObject );
ASSERT_KINDOF( classname, pobject );
ATL 斷言 ATLASSERT( booleanExpression );
此外,TRACE() 宏的編譯也受 _DEBUG 控制。

所有這些斷言都只在 Debug版中才被編譯,而在 Release 版中被忽略。唯一的例外是 VERIFY() 。事實上,這些宏都是調用了 assert() 函數,只不過附加了一些與庫有關的調試代碼。如果你在這些宏中加入了任何程序代碼,而不只是布爾表達式(例如賦值、能改變變數值的函數調用 等),那麼 Release 版都不會執行這些操作,從而造成錯誤。初學者很容易犯這類錯誤,查找的方法也很簡單,因為這些宏都已在上面列出,只要利用 VC++ 的 Find in Files 功能在工程所有文件中找到用這些宏的地方再一一檢查即可。另外,有些高手可能還會加入 #ifdef _DEBUG 之類的條件編譯,也要注意一下。
順便值得一提的是 VERIFY() 宏,這個宏允許你將程序代碼放在布爾表達式里。這個宏通常用來檢查 Windows API 的返回值。有些人可能為這個原因而濫用 VERIFY() ,事實上這是危險的,因為 VERIFY() 違反了斷言的思想,不能使程序代碼和調試代碼完全分離,最終可能會帶來很多麻煩。因此,專家們建議盡量少用這個宏。

4. /GZ 選項:這個選項會做以下這些事

(1) 初始化內存和變數。包括用 0xCC 初始化所有自動變數,0xCD ( Cleared Data ) 初始化堆中分配的內存(即動態分配的內存,例如 new ),0xDD ( Dead Data ) 填充已被釋放的堆內存(例如 delete ),0xFD( deFencde Data ) 初始化受保護的內存(debug 版在動態分配內存的前後加入保護內存以防止越界訪問),其中括弧中的詞是微軟建議的助記詞。這樣做的好處是這些值都很大,作為指針是不可能的(而且 32 位系統中指針很少是奇數值,在有些系統中奇數的指針會產生運行時錯誤),作為數值也很少遇到,而且這些值也很容易辨認,因此這很有利於在 Debug 版中發現 Release 版才會遇到的錯誤。要特別注意的是,很多人認為編譯器會用 0 來初始化變數,這是錯誤的(而且這樣很不利於查找錯誤)。
(2) 通過函數指針調用函數時,會通過檢查棧指針驗證函數調用的匹配性。(防止原形不匹配)
(3) 函數返回前檢查棧指針,確認未被修改。(防止越界訪問和原形不匹配,與第二項合在一起可大致模擬幀指針省略 FPO )

通常 /GZ 選項會造成 Debug 版出錯而 Release 版正常的現象,因為 Release 版中未初始化的變數是隨機的,這有可能使指針指向一個有效地址而掩蓋了非法訪問。

除此之外,/Gm /GF 等選項造成錯誤的情況比較少,而且他們的效果顯而易見,比較容易發現。
--------------------------------------------------------------
Release是發行版本,比Debug版本有一些優化,文件比Debug文件小
Debug是調試版本,包括的程序信息更多
Release方法:
build->batch build->build就OK.

java 編譯優化問題

java編譯的結果是位元組碼而不是二進制,所以在運行時vm的優化才是重要的,包括VM的回收策略、分配給VM內存的大小都能在一定程度上影響性能。Sun的VM支持熱點編譯,對高頻執行的代碼段翻譯的2進制會進行緩存,這也是VM的一種優化。

IBM JVM處理數學運算速度最快,BEA JVM處理大量線程和網路socket性能最好,而Sun JVM處理通常的商業邏輯性能最好。不過Hotspot的Server mode被報告有穩定性的問題。

Java 的最大優勢不是體現在執行速度上,所以對Compiler的要求並不如c++那樣高,代碼級的優化還需要程序員本身的功底。

貼個java的運行參數:

Usage: java [-options] class [args...]
(to execute a class)
or java [-options] -jar jarfile [args...]
(to execute a jar file)

where options include:
-client to select the "client" VM
-server to select the "server" VM
-hotspot is a synonym for the "client" VM [deprecated]
The default VM is client.

-cp <class search path of directories and zip/jar files>
-classpath <class search path of directories and zip/jar files>
A ; separated list of directories, JAR archives,
and ZIP archives to search for class files.
-D<name>=<value>
set a system property
-verbose[:class|gc|jni]
enable verbose output
-version print proct version and exit
-version:<value>
require the specified version to run
-showversion print proct version and continue
-jre-restrict-search | -jre-no-restrict-search
include/exclude user private JREs in the version search
-? -help print this help message
-X print help on non-standard options
-ea[:<packagename>...|:<classname>]
-enableassertions[:<packagename>...|:<classname>]
enable assertions
-da[:<packagename>...|:<classname>]
-disableassertions[:<packagename>...|:<classname>]
disable assertions
-esa | -enablesystemassertions
enable system assertions
-dsa | -disablesystemassertions
disable system assertions
-agentlib:<libname>[=<options>]
load native agent library <libname>, e.g. -agentlib:hprof
see also, -agentlib:jdwp=help and -agentlib:hprof=help
-agentpath:<pathname>[=<options>]
load native agent library by full pathname
-javaagent:<jarpath>[=<options>]
load Java programming language agent, see

java.lang.instrument

-Xmixed mixed mode execution (default)
-Xint interpreted mode execution only
-Xbootclasspath:<directories and zip/jar files separated by ;>
set search path for bootstrap classes and resources
-Xbootclasspath/a:<directories and zip/jar files separated by ;>
append to end of bootstrap class path
-Xbootclasspath/p:<directories and zip/jar files separated by ;>
prepend in front of bootstrap class path
-Xnoclassgc disable class garbage collection
-Xincgc enable incremental garbage collection
-Xloggc:<file> log GC status to a file with time stamps
-Xbatch disable background compilation
-Xms<size> set initial Java heap size
-Xmx<size> set maximum Java heap size
-Xss<size> set java thread stack size
-Xprof output cpu profiling data
-Xfuture enable strictest checks, anticipating future default
-Xrs rece use of OS signals by Java/VM (see

documentation)
-Xcheck:jni perform additional checks for JNI functions
-Xshare:off do not attempt to use shared class data
-Xshare:auto use shared class data if possible (default)
-Xshare:on require using shared class data, otherwise fail.

Java虛擬機(JVM)參數配置說明

在Java、J2EE大型應用中,JVM非標准參數的配置直接關繫到整個系統的性能。
JVM非標准參數指的是JVM底層的一些配置參數,這些參數在一般開發中默認即可,不需

要任何配置。但是在生產環境中,為了提高性能,往往需要調整這些參數,以求系統達

到最佳新能。
另外這些參數的配置也是影響系統穩定性的一個重要因素,相信大多數Java開發人員都

見過「OutOfMemory」類型的錯誤。呵呵,這其中很可能就是JVM參數配置不當或者就沒

有配置沒意識到配置引起的。

為了說明這些參數,還需要說說JDK中的命令行工具一些知識做鋪墊。

首先看如何獲取這些命令配置信息說明:
假設你是windows平台,你安裝了J2SDK,那麼現在你從cmd控制台窗口進入J2SDK安裝目

錄下的bin目錄,然後運行java命令,出現如下結果,這些就是包括java.exe工具的和

JVM的所有命令都在裡面。

-----------------------------------------------------------------------
D:\j2sdk15\bin>java
Usage: java [-options] class [args...]
(to execute a class)
or java [-options] -jar jarfile [args...]
(to execute a jar file)

where options include:
-client to select the "client" VM
-server to select the "server" VM
-hotspot is a synonym for the "client" VM [deprecated]
The default VM is client.

-cp <class search path of directories and zip/jar files>
-classpath <class search path of directories and zip/jar files>
A ; separated list of directories, JAR archives,
and ZIP archives to search for class files.
-D<name>=<value>
set a system property
-verbose[:class|gc|jni]
enable verbose output
-version print proct version and exit
-version:<value>
require the specified version to run
-showversion print proct version and continue
-jre-restrict-search | -jre-no-restrict-search
include/exclude user private JREs in the version search
-? -help print this help message
-X print help on non-standard options
-ea[:<packagename>...|:<classname>]
-enableassertions[:<packagename>...|:<classname>]
enable assertions
-da[:<packagename>...|:<classname>]
-disableassertions[:<packagename>...|:<classname>]
disable assertions
-esa | -enablesystemassertions
enable system assertions
-dsa | -disablesystemassertions
disable system assertions
-agentlib:<libname>[=<options>]
load native agent library <libname>, e.g. -agentlib:hprof
see also, -agentlib:jdwp=help and -agentlib:hprof=help
-agentpath:<pathname>[=<options>]
load native agent library by full pathname
-javaagent:<jarpath>[=<options>]
load Java programming language agent, see

java.lang.instrument
-----------------------------------------------------------------------
在控制台輸出信息中,有個-X(注意是大寫)的命令,這個正是查看JVM配置參數的命

令。

其次,用java -X 命令查看JVM的配置說明:
運行後如下結果,這些就是配置JVM參數的秘密武器,這些信息都是英文的,為了方便

閱讀,我根據自己的理解翻譯成中文了(不準確的地方還請各位博友斧正)
-----------------------------------------------------------------------
D:\j2sdk15\bin>java -X
-Xmixed mixed mode execution (default)
-Xint interpreted mode execution only
-Xbootclasspath:<directories and zip/jar files separated by ;>
set search path for bootstrap classes and resources
-Xbootclasspath/a:<directories and zip/jar files separated by ;>
append to end of bootstrap class path
-Xbootclasspath/p:<directories and zip/jar files separated by ;>
prepend in front of bootstrap class path
-Xnoclassgc disable class garbage collection
-Xincgc enable incremental garbage collection
-Xloggc:<file> log GC status to a file with time stamps
-Xbatch disable background compilation
-Xms<size> set initial Java heap size
-Xmx<size> set maximum Java heap size
-Xss<size> set java thread stack size
-Xprof output cpu profiling data
-Xfuture enable strictest checks, anticipating future default
-Xrs rece use of OS signals by Java/VM (see

documentation)
-Xcheck:jni perform additional checks for JNI functions
-Xshare:off do not attempt to use shared class data
-Xshare:auto use shared class data if possible (default)
-Xshare:on require using shared class data, otherwise fail.

The -X options are non-standard and subject to change without notice.
-----------------------------------------------------------------------

JVM配置參數中文說明:
-----------------------------------------------------------------------
1、-Xmixed mixed mode execution (default)
混合模式執行

2、-Xint interpreted mode execution only
解釋模式執行

3、-Xbootclasspath:<directories and zip/jar files separated by ;>
set search path for bootstrap classes and resources
設置zip/jar資源或者類(.class文件)存放目錄路徑

3、-Xbootclasspath/a:<directories and zip/jar files separated by ;>
append to end of bootstrap class path
追加zip/jar資源或者類(.class文件)存放目錄路徑

4、-Xbootclasspath/p:<directories and zip/jar files separated by ;>
prepend in front of bootstrap class path
預先載入zip/jar資源或者類(.class文件)存放目錄路徑

5、-Xnoclassgc disable class garbage collection
關閉類垃圾回收功能

6、-Xincgc enable incremental garbage collection
開啟類的垃圾回收功能

7、-Xloggc:<file> log GC status to a file with time stamps
記錄垃圾回日誌到一個文件。

8、-Xbatch disable background compilation
關閉後台編譯

9、-Xms<size> set initial Java heap size
設置JVM初始化堆內存大小

10、-Xmx<size> set maximum Java heap size
設置JVM最大的堆內存大小

11、-Xss<size> set java thread stack size
設置JVM棧內存大小

12、-Xprof output cpu profiling data
輸入CPU概要表數據

13、-Xfuture enable strictest checks, anticipating future default
執行嚴格的代碼檢查,預測可能出現的情況

14、-Xrs rece use of OS signals by Java/VM (see

documentation)
通過JVM還原操作系統信號

15、-Xcheck:jni perform additional checks for JNI functions
對JNI函數執行檢查

16、-Xshare:off do not attempt to use shared class data
盡可能不去使用共享類的數據

17、-Xshare:auto use shared class data if possible (default)
盡可能的使用共享類的數據

18、-Xshare:on require using shared class data, otherwise fail.
盡可能的使用共享類的數據,否則運行失敗

The -X options are non-standard and subject to change without notice.

④ gcc的O2優化為什麼會有這樣奇怪的問題

感覺可能是是程序的bug,而不是編譯的bug
前面v.n已經提到了這是strict-aliasing優化的問題,但是,
編譯器是可以這么假定的,如果代碼嚴格符合c99

An object shall have its stored value accessed only by an lvalue expression
that has one of the following types:
* a type compatible with the effective type of the object,
* a qualified version of a type compatible with the effective type of
the object,
* a type that is the signed or unsigned type corresponding to the
effective type of the object,
* a type that is the signed or unsigned type corresponding to a qualified
version of the effective type of the object,
* an aggregate or union type that includes one of the aforementioned types
among its members (including, recursively, a member of a subaggregate or
contained union), or
* a character type.

A clear explanation about strict-aliasing rule could be found at:
http://www.cellperformance.com/mike_acton/2006/06/understanding_strict_aliasing.html

⑤ 編譯後出現了情況,請問怎麼解決如圖所示

int x;記得當中的空格
樓主用的是turbo C吧,這東西古老得和SVR4一個年代的,能在win7里跑起來已經是奇跡了,目測像是沒有導入頭文件地址的環境變數導致編譯器讀不出頭文件。gcc 下用-I指定頭文件地址就好了,turbo的話真不太清楚怎麼搞
樓主如果是入門學C的話最好裝個cygwin或者vc 6.0(貌似這個在win7下也有問題),如果樓主不擅長命令行或者不擅長解決編譯問題的最好還是裝個visual studio 08以後的版本,這個編譯器雖然慢但是在現在的系統上絕對穩定。個人極其討厭turbo C,現在國內教科書還在用turbo本身就是一件很奇葩的事,這個編譯器接受的語法根本就不規范,c89定義的main函數要麼是int main()最後返回0要麼void main(),直接上main()是40年前v7的寫法,樓主盡量換本靠譜點的教材學吧,如果是學校教科書的話還是裝個虛擬機在win98上裝這個turbo(也不保證98上穩定性,turbo實在太古老了)

⑥ java編譯器的代碼優化問題

理論上的就不說了,你自己搜也能搜到很多。
舉個例子,你從一個方法a調用了另一個方法b。
我們知道,在a和b之中是可以創建相同名稱的變數的,比如都有int i = 0;這句話。這種現象的根本原因在於,方法的調用會產生中斷,中斷產生後,cpu會做現場保護,包括把變數等進行壓棧操作,即把方法a的相關資源進行了壓棧,而方法b的相關資源放在棧頂,只有棧頂資源可以與cpu交互(就把方法a中的變數i保護起來),當方法b結束後出棧,a就又回到了棧頂,並獲取了方法b運行的結果,然後繼續運行。

哎,有些啰嗦了。方法的調用、中斷、壓棧出棧等等這些操作你說一點不消耗資源吧,那是不可能的,多少都會消耗一些,雖然很非常十分微不足道。那麼編譯器的優化過程,我知道的其作用之一,就是會把這些做一個優化。原本方法a一共10句話,你偏要只寫1句,然後第2句寫成方法b,第3句寫成方法c。。。。。,然後依次嵌套調用。這樣的源代碼,編譯器優化後,就跟你直接寫10句是一個結果,即做了一定程度上的優化。

⑦ 如何防止因編譯器開啟優化,而導致程序執行錯誤

我的經驗是:未優化的c程序可正常運行,優化後不能運行,那一定是我的程序有問題。我還沒經歷過不是我程序的情況。
發現這種不易發現的問題,需要看匯編碼。
避免的方法,我的經驗:寫c程序,盡量規矩;似是而非的概念,一定要搞清楚,別僥幸。因為僥幸而留的雷,現在不出問題,將來一定會出問題;不優化不出問題,優化就出問題。
最後要說,每個應用程序,都讓他開優化運行,只要時間允許,一定要查出開優化後出問題的原因。時間不允許,只能不開優化湊合著,在有時間的時候繼續查問題。

⑧ ARMClang6.1編譯優化導致的訪問不對齊異常

keil-project-options for target-選項卡c/c++ 左側中間有個optimization 後面的對應的就是編譯優化設置 level 0就是不優化

⑨ 編譯器的編譯器優化

應用程序之所以復雜, 是由於它們具有處理多種問題以及相關數據集的能力。實際上, 一個復雜的應用程序就象許多不同功能的應用程序「 粘貼」 在一起。源文件中大部分復雜性來自於處理初始化和問題設置代碼。這些文件雖然通常占源文件的很大一部分, 具有很大難度, 但基本上不花費C PU 執行周期。
盡管存在上述情況, 大多數Makefile文件只有一套編譯器選項來編譯項目中所有的文件。因此, 標準的優化方法只是簡單地提升優化選項的強度, 一般從O 2 到O 3。這樣一來, 就需要投人大量 精力來調試, 以確定哪些文件不能被優化, 並為這些文件建立特殊的make規則。
一個更簡單但更有效的方法是通過一個性能分析器, 來運行最初的代碼, 為那些佔用了85 一95 % CPU 的源文件生成一個列表。通常情況下, 這些文件大約只佔所有文件的1%。如果開發人員立刻為每一個列表中的文件建立其各自的規則, 則會處於更靈活有效的位置。這樣一來改變優化只會引起一小部分文件被重新編譯。進而,由於時間不會浪費在優化不費時的函數上, 重編譯全部文件將會大大地加快。

閱讀全文

與編譯器開啟優化後出現了其他問題相關的資料

熱點內容
編程培訓機構學費 瀏覽:499
華為麥芒5伺服器地址 瀏覽:744
怎麼把app裡面的app上鎖 瀏覽:938
java數字運算 瀏覽:164
java讀取上傳的文件 瀏覽:373
xp怎麼加密文檔 瀏覽:273
壓縮機風扇電機轉速慢 瀏覽:88
文件伺服器如何查看訪問人員 瀏覽:127
絕佳買賣指標加密 瀏覽:758
git分支編譯 瀏覽:156
51單片機c語言應用程序設計實例精講 瀏覽:562
華為安卓手機編譯器 瀏覽:48
怎樣在打開微信前加密 瀏覽:666
旺旺聊天記錄怎麼加密 瀏覽:413
王安憶長恨歌pdf 瀏覽:621
mobile文件夾可以卸載嗎 瀏覽:282
什麼是2通道伺服器 瀏覽:346
mc正版怎麼開伺服器地址 瀏覽:408
樂高解壓朋友圈 瀏覽:14
linux軟raid性能 瀏覽:369