First time using g++...

closed account (10oTURfi)
I got a program which compiles fine in MSVC++, but on g++ it generates hundreds of errors. They mostly look like this:

player.h:149: error: base operand of ‘->’ is not a pointer
player.h:151: error: invalid type argument of ‘unary *’
player.h:152: error: ISO C++ forbids declaration of ‘atr_itr’ with no type
player.h:152: error: base operand of ‘->’ is not a pointer
player.h:152: error: base operand of ‘->’ is not a pointer
player.h:154: error: base operand of ‘->’ is not a pointer
player.h:157: error: base operand of ‘->’ is not a pointer
player.h:160: error: base operand of ‘->’ is not a pointer
player.h:163: error: base operand of ‘->’ is not a pointer
player.h:166: error: base operand of ‘->’ is not a pointer


And this is the function at those lines in player.h

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
35
void EquipItem(Item Item) // LINE 145
    {
        for(auto itr = EquipedItems.begin(); itr != EquipedItems.end(); ++itr)
        {
            if(itr->Type == Item.Type)
            {
                Items.push_back(*itr);
                for(auto atr_itr = itr->Attributes.begin(); atr_itr != itr->Attributes.end(); ++atr_itr)
                {
                    switch(atr_itr->Attribute)
                    {
                    case HEALTH:
                        SetMaxHealth(MaxHealth - atr_itr->Value);
                        continue;
                    case POWER:
                        SetMaxPower(MaxPower - atr_itr->Value);
                        continue;
                    case ATTACK_POWER:
                        SetAttack(Attack - atr_itr->Value);
                        continue;
                    case DEFENSE_POWER:
                        SetDefense(Defense - atr_itr->Value);
                        continue;
                    case INT_OR_STR:
                        SetIntStr(IntStr - atr_itr->Value);
                        continue;
                    }
                }
                EquipedItems.erase(itr);
                break;
            }
        }
        EquipedItems.push_back(Item);
        CalculateStatsFromEquip();
    }



Some errors, however, are not readable by humans, such as this one:

player.h:173: error: no matching function for call to ‘std::vector<Item, std::allocator<Item> >::erase(int&)’
/usr/include/c++/4.4/bits/vector.tcc:133: note: candidates are: __gnu_cxx::__normal_iterator<typename std::_Vector_base<_Tp, _Alloc>::_Tp_alloc_type::pointer, std::vector<_Tp, _Alloc> > std::vector<_Tp, _Alloc>::erase(__gnu_cxx::__normal_iterator<typename std::_Vector_base<_Tp, _Alloc>::_Tp_alloc_type::pointer, std::vector<_Tp, _Alloc> >) [with _Tp = Item, _Alloc = std::allocator<Item>]
/usr/include/c++/4.4/bits/vector.tcc:145: note: __gnu_cxx::__normal_iterator<typename std::_Vector_base<_Tp, _Alloc>::_Tp_alloc_type::pointer, std::vector<_Tp, _Alloc> > std::vector<_Tp, _Alloc>::erase(__gnu_cxx::__normal_iterator<typename std::_Vector_base<_Tp, _Alloc>::_Tp_alloc_type::pointer, std::vector<_Tp, _Alloc> >, __gnu_cxx::__normal_iterator<typename std::_Vector_base<_Tp, _Alloc>::_Tp_alloc_type::pointer, std::vector<_Tp, _Alloc> >) [with _Tp = Item, _Alloc = std::allocator<Item>]
player.h: In member function ‘void Player::RemoveItem(int)’:
player.h:183: error: ISO C++ forbids declaration of ‘itr’ with no type
player.h:183: error: cannot convert ‘__gnu_cxx::__normal_iterator<Item*, std::vector<Item, std::allocator<Item> > >’ to ‘int’ in initialization
player.h:184: error: no matching function for call to ‘std::vector<Item, std::allocator<Item> >::erase(int&)’
/usr/include/c++/4.4/bits/vector.tcc:133: note: candidates are: __gnu_cxx::__normal_iterator<typename std::_Vector_base<_Tp, _Alloc>::_Tp_alloc_type::pointer, std::vector<_Tp, _Alloc> > std::vector<_Tp, _Alloc>::erase(__gnu_cxx::__normal_iterator<typename std::_Vector_base<_Tp, _Alloc>::_Tp_alloc_type::pointer, std::vector<_Tp, _Alloc> >) [with _Tp = Item, _Alloc = std::allocator<Item>]
/usr/include/c++/4.4/bits/vector.tcc:145: note: __gnu_cxx::__normal_iterator<typename std::_Vector_base<_Tp, _Alloc>::_Tp_alloc_type::pointer, std::vector<_Tp, _Alloc> > std::vector<_Tp, _Alloc>::erase(__gnu_cxx::__normal_iterator<typename std::_Vector_base<_Tp, _Alloc>::_Tp_alloc_type::pointer, std::vector<_Tp, _Alloc> >, __gnu_cxx::__normal_iterator<typename std::_Vector_base<_Tp, _Alloc>::_Tp_alloc_type::pointer, std::vector<_Tp, _Alloc> >) [with _Tp = Item, _Alloc = std::allocator<Item>]
player.h: In member function ‘void Player::CalculateStatsFromEquip()’:
player.h:189: error: ISO C++ forbids declaration of ‘itr’ with no type
player.h:189: error: cannot convert ‘__gnu_cxx::__normal_iterator<Item*, std::vector<Item, std::allocator<Item> > >’ to ‘int’ in initialization
player.h:189: error: no match for ‘operator!=’ in ‘itr != ((Player*)this)->Player::EquipedItems.std::vector<_Tp, _Alloc>::end [with _Tp = Item, _Alloc = std::allocator<Item>]()’
player.h:191: error: ISO C++ forbids declaration of ‘iter’ with no type
player.h:191: error: base operand of ‘->’ is not a pointer
player.h:191: error: base operand of ‘->’ is not a pointer
player.h:193: error: base operand of ‘->’ is not a pointer
player.h:196: error: base operand of ‘->’ is not a pointer
player.h:197: error: base operand of ‘->’ is not a pointer
player.h:200: error: base operand of ‘->’ is not a pointer
player.h:201: error: base operand of ‘->’ is not a pointer
player.h:204: error: base operand of ‘->’ is not a pointer
player.h:207: error: base operand of ‘->’ is not a pointer
player.h:210: error: base operand of ‘->’ is not a pointer


In this error, compiler complains about this code:

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
35
    void RemoveItem(int Iter) // Line 181
    {
        auto itr = Items.begin() + Iter;
        Items.erase(itr);
    }

    void CalculateStatsFromEquip()
    {
        for(auto itr = EquipedItems.begin(); itr != EquipedItems.end(); ++itr)
        {
            for(auto iter = itr->Attributes.begin(); iter != itr->Attributes.end(); ++iter)
            {
                switch(iter->Attribute)
                {
                case HEALTH:
                    MaxHealth += iter->Value;
                    Health += iter->Value;
                    continue;
                case POWER:
                    MaxPower += iter->Value;
                    Power += iter->Value;
                    continue;
                case ATTACK_POWER:
                    Attack += iter->Value;
                    continue;
                case DEFENSE_POWER:
                    Defense += iter->Value;
                    continue;
                case INT_OR_STR:
                    IntStr += iter->Value;
                    continue;
                }
            }
        }
    }



Can anyone tell me where is the problem?
I think that you need -std=c++0x in order to use auto in that way.
Well that and comparing MSVC++ to GNU's G++(GNU's C++ compiler) is like comparing apples and oranges. MSVC++ is the trolling inbred cousin to G++ as it doesn't adhere to the C++ standard strictly like it should, but rather takes parts of the standards and then puts in Microsoft's ideas of what the other elements of the standard should be. One reason I didn't touch MSVC++ before I used G++ for a long time.
Last edited on by closed account z6A9GNh0
@BHXSpecter
And your suggesting GCC does strictly adhere to the standard? I seem to remember GCC allows stack arrays to be initialised with non constant size, I believe that goes against the standard.
closed account (1yR4jE8b)
GCC has some extensions to the C++ language, but most of them are easily disabled. That one particular feature you talk about is a part of it's support for C99, which is why it's possible with C++.

You can disable these extensions with combinations of -pedantic, -Wall, and -std= command line switches.
closed account (10oTURfi)
I also noticed that MSVC++ allowed me to do this:
1
2
struct Foo {};
Foo Foo;

While g++ doesn't. I had to rewrite hundreds of lines just for that...
1
2
struct Foo {};
Foo Foo;


But that is perfectly legal in C++
closed account (10oTURfi)
@guestgulkan
That makes it even more annoying.

This is error it produces:
In file included from player.h:21,
from game.h:20,
from main.cpp:23:
item.h:11: error: declaration of ‘Attribute ItemAttribute::Attribute’
include.h:60: error: changes meaning of ‘Attribute’ from ‘enum Attribute’
In file included from game.h:22,
from main.cpp:23:
enemy.h:28: error: declaration of ‘Item Loot::Item’
item.h:15: error: changes meaning of ‘Item’ from ‘struct Item’
In file included from game.h:22,
from main.cpp:23:
enemy.h:48: error: declaration of ‘std::vector<Loot, std::allocator<Loot> > Enemy::Loot’
enemy.h:25: error: changes meaning of ‘Loot’ from ‘struct Loot’
In file included from main.cpp:23:
game.h:32: error: declaration of ‘Player Game::Player’
player.h:25: error: changes meaning of ‘Player’ from ‘class Player’
@Krofna g++ doesn't allow this:
1
2
struct Foo{};
Foo Foo;


GNU G++ under Ubuntu allows it just fine:

http://twitpic.com/9880vd/full
Last edited on by closed account z6A9GNh0
closed account (10oTURfi)
Woah, looks like a bad example. Compile this:
1
2
3
4
5
6
7
8
9
10
struct Bar
{
};
struct Foo
{
    Bar Bar;
};
int main()
{
}


$ g++ main.cpp
main.cpp:6: error: declaration of ‘Bar Foo::Bar’
main.cpp:2: error: changes meaning of ‘Bar’ from ‘struct Bar’
Last edited on
Not sure. For some reason it is thinking Bar is derived from Foo. Oddly if I changed it to:

1
2
3
4
5
struct Bar{};
struct Foo{Bar bar;};
int main()
{
}


It compiles fine. Guess g++ thinks it is bad code to do the other way.

You could add [-fpermissive] to the compile line and it will compile but the errors will become warnings.
Last edited on by closed account z6A9GNh0
It doesn't work because you are using the same name for the type and the variable, Bar Bar;. You shouldn't do that. How can the compiler know, inside Foo's code, if you are referring to the type Bar or the variable Bar?

BHXSpecter wrote:
For some reason it is thinking Bar is derived from Foo.

Actually, the error message means the variable Bar (Bar Foo::Bar), member of Foo (Bar Foo::Bar), of type Bar (Bar Foo::Bar). And your example works because you changed the case on the variable name.
Yeah looking back at my code tests the derived error I got was when I changed something else in the code. Like you pointed out though, it is poor programming practice to do Bar Bar (unless it is a class constructor) or using the same name in type and variable. Bar Bar would be like trying to make int int; in a program.
Topic archived. No new replies allowed.