아래의 결과는 버그 리포트를 개선하고 문제 해결을 위해 코드를 사용하는 데 유용 할 것으로 생각됩니다.
최적화 된 출력을 디버깅하고 최적화 플래그 및 마이너 코드 변경 사항을 재생하여 오류의 원인이되는 특정 최적화 플래그에 대한 결론에 도달했습니다.
옵션의 설정은 다음과 같습니다
-O -fno-auto-inc-dec -fno-branch-count-reg -fno-combine-stack-adjustments -fno-compare-elim -fno-cprop-registers -fno-dce -fno-defer-pop -fno-delayed-branch -fno-dse -fno-forward-propagate -fno-guess-branch-probability -fno-if-conversion2 -fno-if-conversion -fno-inline-functions-called-once -fno-ipa-pure-const -fno-ipa-profile -fno-ipa-reference -fno-merge-constants -fno-move-loop-invariants -fno-reorder-blocks -fno-shrink-wrap -fno-split-wide-types -fno-ssa-backprop -fno-ssa-phiopt -fno-tree-bit-ccp -fno-tree-ccp -fno-tree-ch -fno-tree-coalesce-vars -fno-tree-phiprop -fno-tree-sink -fno-tree-slsr -fno-tree-dse -fno-tree-forwprop -fno-tree-fre -fno-unit-at-a-time -fno-tree-ter -fno-tree-sra -fno-tree-copy-prop -fstrict-aliasing -ftree-slp-vectorize -std=c++14
그 시간을 설정할 죄송하지만 실제로 원하는 것은 같은 것이었다 : O1의 -O0 -ftree-copy-prop -ftree-pta -ftree-dce -fstrict-aliasing -ftree-slp-vectorize
(나는 또한 -OG으로 시도했다)을 더한 마법의 단계를 .. . 단지 -O3 -f-no-tree-slp-vectorize
이미 문제를 해결하지만, 전체 옵션을 사용하여합니다
참고 나는 또한 ... 디버깅 거의 쉽게
을 보낸, 그것은 운영자 ==(string, string)
의 존재처럼 보이는 생성하는 컴파일러의 혼란.
#if 0 코드로 주석 처리 된 모든 코드가 원래 코드 대신 작동 할 때 붙여 넣은 코드를 살펴보면 내가하지 않은 곳에서 문제가 발생할 수 있습니다.
==()
연산자는 심지어 테스트에서 foo.a != '\0'
이 항상 true이기 때문에 호출조차되지 않습니다. 따라서 컴파일러가 잘못된 코드를 생성하는 것이 존재하는 것처럼 보입니다.
또한 루프 내부의 주석 처리 된 코드는 예상되는 동작으로 동작을 변경하기 때문에 처음에는 벡터화 플래그가 의심됩니다.
#include <string>
#include <deque>
#include <iterator>
#include <iostream>
#include <boost/iterator/filter_iterator.hpp>
#include <string.h>
struct Foo
{
std::string bar, s = "";
char a = 'n';
};
std::ostream& operator<<(std::ostream& os, const Foo& f)
{
os << f.bar << '/' << f.a;
return os;
}
int main()
{
std::deque<Foo> foos(14, {"abc"});
const std::string test {"abc"};
Foo other;
other.bar = "last"; other.a = 'l';
foos.push_back(other);
other.bar = "first";
other.a = 'f';
foos.push_front(other);
//
#if 0
const auto p = [test] (const auto& foo) { return foo.a != '\0'; };
#elif 0
const auto p = [test] (const auto& foo) {
bool rc = (foo.a != '\0');
if (!rc)
rc = (foo.bar == std::string(test));
return rc;
};
#elif 1
const auto p = [test] (const auto& foo) {
bool rc = (foo.a != '\0');
if (!rc)
rc = (foo.bar == test);
return rc;
};
#endif
using boost::make_filter_iterator;
const auto begin = make_filter_iterator(p, std::cbegin(foos), std::cend(foos));
const auto end = make_filter_iterator(p, std::cend(foos), std::cend(foos));
std::cout << std::distance(end, end) << std::endl;
std::cout << std::distance(begin, begin) << std::endl;
std::cout << std::distance(std::cbegin(foos), std::cend(foos)) << std::endl;
auto __first = begin;
auto __last = end;
int __n = 0;
//std::cout << __last << std::endl;
//std::deque<char> trace;
//Foo trace[21];
const int max = foos.size();
char trace[max+5]; memset(trace, 'c', sizeof(trace));
std::cout << max << std::endl;
std::cout << *__last << std::endl;
while (__first != __last)
{
trace[__n] = (*__first).a;
//trace[__n] = (*__first);
//trace.push_back((*__first).a);
//std::cout << *__first << std::endl;
++__n;
++__first;
if (__n > max + 5)
break;
//std::cout << __n << std::endl;
//std::cout << (__first != __last) << std::endl;
}
for (auto f: trace)
std::cout << f << std::endl;
std::cout << "Tadaaaaa: " << __n << std::endl;
//std::cout << std::distance(begin, end) << std::endl;
}
어떤 부스트 버전을 사용하고 있습니까 –
@ M.M boost 1.61. – Daniel
또한 어떤 플랫폼을 사용하고 계십니까? (i686-x86_84?) –