[英]why optimization breaks this C code?
有誰知道為什么-O2打破了這段代碼? 我懷疑它是gcc中的一個錯誤,因為它可以在不同平台和不同版本的gcc上正常工作。 但是,代碼也可能包含一些我不知道的特性。 誰能開導我?
這是代碼,它是可變數量的嵌套循環的實現,產生所有可能的組合。 預期的產出是
100 1
010 2
001 4
110 3
101 5
和破碎的版本報告
100 1
010 2
001 4
100 1
010 2
代碼是:
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
int main()
{
int nmax = 5; // finish after 5 combinations
int n = 3; // three elements
int *out = (int*) calloc(nmax, sizeof(int));
int *cnt = (int*) calloc(n, sizeof(int)); // declaring volatile solves the problem. But why ?
int il, nl, i = 0;
for (nl=1; nl<=n; nl++)
{
for (il=0; il<nl; il++) cnt[il] = 0;
cnt[nl-1] = -1;
while ( cnt[0]<n-nl )
{
for (il=nl-1; il>=0; il--)
{
if ( ++cnt[il] < n-nl+il+1 ) break;
cnt[il] = 0;
}
for (il=1; il<nl; il++)
{
if ( cnt[il] <= cnt[il-1] ) cnt[il] = cnt[il-1]+1;
}
for (il=0; il<nl; il++) out[i] |= 1<<cnt[il];
if ( ++i >= nmax ) break;
}
if ( i >= nmax ) break;
}
for (i=0; i<nmax; i++)
{
for (il=0; il<n; il++) printf("%d", out[i]&(1<<il) ? 1 : 0);
printf("\t%d\n", out[i]);
}
free(cnt);
free(out);
return 0;
}
您應該發布您正在使用的gcc版本,目標以及您正在使用的確切命令行的詳細信息。 另外,發布GCC生成的程序集(例如,使用-S
選項)會很有幫助。
我猜測編譯器錯誤地將cnt[0]
從while
循環控制表達式中提升出來。 以下修改(將模擬提升機)產生不正確的輸出:
// ...
for (nl=1; nl<=n; nl++)
{
int tmp; // <== new line
for (il=0; il<nl; il++) cnt[il] = 0;
cnt[nl-1] = -1;
tmp = cnt[0]; // <== new line
while ( /*cnt[0] */ tmp <n-nl ) // modified
{
for (il=nl-1; il>=0; il--)
// ...
當然,這只是猜測 - 獲取所請求的詳細信息會更有趣,因此可以檢查生成的代碼。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.