GCC vs. LLVM

Why does this work with LLVM 2.0, but not with GCC 4.2 ??

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include <iostream>
#include <vector>
#include <list>

using namespace std;

bool compare(const int &lhs, const int &rhs){
    cout << lhs << "-" << rhs << " ";
    return (lhs < rhs);
}

template <typename T, typename comp>
bool test(T begin, T end, comp cmp) {
    --end;
    for(;cmp(*begin++, *begin) && (begin != end););
    if (begin == end) return true;
    return false;
}

int main (int argc, const char * argv[])
{
    vector<int> vec;
    list<int> lis;
    
    for (int i = 0; i < 10; i++) {
        lis.push_back(i);
        vec.push_back(i);
    }

    cout << test(lis.begin(), lis.end(), compare) << endl;
    cout << test(vec.begin(), vec.end(), compare);
    
    return 0;
}


LLVM Output
0-1 1-2 2-3 3-4 4-5 5-6 6-7 7-8 8-9 1
0-1 1-2 2-3 3-4 4-5 5-6 6-7 7-8 8-9 1


GCC Output
0-0 0
0-0 0


Thanks
You have not one, but two (count 'em!) problems:

1. You have a specifically "undefined behavior" -- meaning that you are relying upon a side effect that is not guaranteed. This is permitted to work differently (or not at all, or randomly) on different compilers. See http://www.parashift.com/c++-faq-lite/misc-technical-issues.html#faq-39.15 for more.

2. If your predicate returns properly, you should only see the output for one item. This is an error with the way LLVC is compiling your program. Are you using any unusual compiler directives?

Also, you are doing something screwy with the end argument. (Don't do that.) Your function should look something like this:
1
2
3
4
5
6
template <typename T, typename P>
bool test(T begin, T end, P p) {
    for(; (begin != end) && p(*begin, *begin); )
        /* no body */ ;
    return (begin == end);
}

Hope this helps.
If your predicate returns properly, you should only see the output for one item
sorry, ¿why?

¿Is this what is it supposed to do?
1
2
3
4
5
6
7
8
template <typename T, typename P>
bool test(T begin, T end, P p) {
    if( begin == end ) return true; //empty list
    for( /* */ )
        if( not p(*prev, *it) )
            return false;
    return true;
}
Duoas: Are you sure about #2? Doesn't it depend on the order of evaluation of post-increment?
I don't think so --- but I could be wrong. All rules are off when it comes to argument list evaluation...

It seems I misread the intent of the function -- op wants to validate that the list is in strictly increasing order?
Topic archived. No new replies allowed.