2015-11-21 13 views
6

Ich habe mein Problem zu dem folgenden kurzen Programm zusammengefasst.SEGFAULT im -O3-Modus?

Es verursacht SEGFAULT nur im Modus -O3 (-O2 funktioniert einwandfrei). Nach gdb passiert es bei *f = 0 Zeile.

#include <iostream> 

void func1(int s, int t) 
{ 
     char* buffer = new char[s + t*sizeof(float)]; 
     if (!buffer) 
     { 
      std::cout << "new failed\n"; 
      return; 
     } 
     float* f = (float*)(buffer + s); 
     for (int i = 0; i < t; ++i) 
     { 
      *f = 0; 
      //std::cout << i << std::endl; // if uncomment this line everything will work fine 
      ++f; 
     } 
     delete [] buffer; 
     std::cout << "done\n"; 
} 

int main() 
{ 
     int s = 31, t = 12423138; 
     std::cout << s << " " << t << std::endl; 
     func1(s, t); 
     return 0; 
} 

Bitte lassen Sie mich wissen, was mache ich falsch?

+8

Das ist eine grobe Verletzung der [strengen Aliasing-Regel] ist (http : //stackoverflow.com/questions/98650/what-is-the-strict-aliasing-rule). Was den Absturz betrifft, liegt es wahrscheinlich daran, dass Sie auf nicht ausgerichtete Daten zugreifen. Aufgrund des Alias-Problems kann es nicht helfen, aber versuchen Sie, mit mehr Warnungen zu kompilieren (z. B. "-Wand -Wextra -pedantisch") und sehen Sie, ob es Ihnen etwas sagt. –

+0

@JoachimPileborg Ich kompilierte diesen Code auf MSVC mit -W4 -Wx, und es kompiliert gut. –

+1

AFAIK MSVC++ nimmt niemals strenge Aliasing-Regeln an und macht keine Optimierungen von diesen Regeln abhängig. –

Antwort

2

Die Quelle von SEGFAULT war nicht nur eine Verletzung der strengen Aliasing-Regel, da das Problem auch mit dem Flag -no-strict-aliasing bestehen blieb.

Es war in der Tat Zugriff auf nicht ausgerichteten Speicher, aber nicht so einfach. Als moderne Prozessoren erlauben sie im Allgemeinen einen nicht ausgerichteten Speicherzugriff, und es gibt heutzutage nicht viel Aufwand. Ich habe ein Benchmarking durchgeführt und habe keinen großen Unterschied zwischen dem algined vs unaligned Read auf meiner Intel (R) Xeon (R) CPU E5-2680 v2 @ 2.80GHz beobachtet. Auch gibt es some sehr ähnliche (und mehr oder weniger aktuelle) Ergebnisse im Web.

Mein Problem war, dass -O3 Modus -ftree-vectorize Flag ermöglicht daher mein for Zyklus vektorisiert wurde (wie ich -ftree-vectorizer-verbose Flag verwendet sehen konnte). Und (AFAIU) gibt es keine Unterstützung (noch?) Für nicht ausgerichteten Speicherzugriff unter Verwendung von vektorisierten Anweisungen, so dass es eine Laufzeitausnahme gab.

This article half mir viel zum Verständnis der Theorie aus, obwohl es, dass heute nicht ausgerichteten Speicherzugriff scheint, ist nicht so schädlich, wie es war, aber immer noch heikel