public inbox for gcc-help@gcc.gnu.org
 help / color / mirror / Atom feed
* RE: error: 'cit' was not declared in this scope
@ 2009-12-29 19:49 Gerry Sweeney
  2009-12-29 20:45 ` John S. Fine
  0 siblings, 1 reply; 8+ messages in thread
From: Gerry Sweeney @ 2009-12-29 19:49 UTC (permalink / raw)
  To: gcc-help

Hi,

I am trying to port some code from VC9 to Linux using "gcc (Ubuntu 
4.4.1-4ubuntu8) 4.4.1" and I am getting an error with GCC that I don't get 
when compiling under VC9.

test.cpp: In member function 'const Value& enums_map<Key, 
Value>::operator[](const Key&) const':
test.cpp:30: error: expected ';' before 'cit'
test.cpp:31: error: 'cit' was not declared in this scope

The problem is I need to create a local variable of type <the base 
class>::const_iterator but I cant work out how I can do this. As I 
mentioned, the code below works when compiling under VC9 but not with g++. I 
can't work out how to solve this problem, could anyone help? This is the 
code sample (just compiling with "g++ test.cpp"

---------------------------------<snip>-------------------------------------
#include <stdio.h>
#include <string>
#include <iostream>
#include <tr1/regex>
#include <inttypes.h>
#include <stdarg.h>

#include <map>


// Just the std::map, plus a const version of operator[] which returns a 
const reference to a const member template<typename Key, typename Value> 
class enums_map : public std::map<Key, Value> {
        typedef std::map<Key, Value> base_type;

public:
        enums_map()
                : default_value_()
        {
        }

        enums_map(const Value& default_value)
                : default_value_(default_value)
        {
        }

        const Value& operator[] (const Key& key) const
        {
                base_type::const_iterator cit = base_type::find(key);
                if (cit == base_type::end())
                        return default_value_;
                else
                        return cit->second;
        }

        using base_type::operator[];

private:
        const Value default_value_;
};
---------------------------------<snip>-------------------------------------

Any help very much appreciated

Thanks,

Gerry



^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: error: 'cit' was not declared in this scope
  2009-12-29 19:49 error: 'cit' was not declared in this scope Gerry Sweeney
@ 2009-12-29 20:45 ` John S. Fine
  2009-12-30  3:49   ` Gerry Sweeney
  0 siblings, 1 reply; 8+ messages in thread
From: John S. Fine @ 2009-12-29 20:45 UTC (permalink / raw)
  To: Gerry Sweeney; +Cc: gcc-help

You are focusing on the second error, but that was just a consequence of 
the first.

During the initial parsing, the compiler doesn't know that types from 
the base class are types, because it doesn't know what the base class 
will be until it has the template actuals.

You can tell it that types are types using the typename keyword in each 
place where you use them.

I think that is a bad style, and it is better to bring such types into 
the current class with a typedef as in

       typedef std::map<Key, Value> base_type;
       typedef typename base_type::const_iterator const_iterator;
...
       const_iterator cit = base_type::find(key);

But in similar style, I also think "using" is better than individual 
overrides for functions that should be inherited from the base class:

       typedef std::map<Key, Value> base_type;
       typedef typename base_type::const_iterator const_iterator;
       using base_type::find;
...
       const_iterator cit = find(key);

Gerry Sweeney wrote:
> Hi,
>
> I am trying to port some code from VC9 to Linux using "gcc (Ubuntu 
> 4.4.1-4ubuntu8) 4.4.1" and I am getting an error with GCC that I don't 
> get when compiling under VC9.
>
> test.cpp: In member function 'const Value& enums_map<Key, 
> Value>::operator[](const Key&) const':
> test.cpp:30: error: expected ';' before 'cit'
> test.cpp:31: error: 'cit' was not declared in this scope
>
> The problem is I need to create a local variable of type <the base 
> class>::const_iterator but I cant work out how I can do this. As I 
> mentioned, the code below works when compiling under VC9 but not with 
> g++. I can't work out how to solve this problem, could anyone help? 
> This is the code sample (just compiling with "g++ test.cpp"
>
> ---------------------------------<snip>------------------------------------- 
>
> #include <stdio.h>
> #include <string>
> #include <iostream>
> #include <tr1/regex>
> #include <inttypes.h>
> #include <stdarg.h>
>
> #include <map>
>
>
> // Just the std::map, plus a const version of operator[] which returns 
> a const reference to a const member template<typename Key, typename 
> Value> class enums_map : public std::map<Key, Value> {
>        typedef std::map<Key, Value> base_type;
>
> public:
>        enums_map()
>                : default_value_()
>        {
>        }
>
>        enums_map(const Value& default_value)
>                : default_value_(default_value)
>        {
>        }
>
>        const Value& operator[] (const Key& key) const
>        {
>                base_type::const_iterator cit = base_type::find(key);
>                if (cit == base_type::end())
>                        return default_value_;
>                else
>                        return cit->second;
>        }
>
>        using base_type::operator[];
>
> private:
>        const Value default_value_;
> };
> ---------------------------------<snip>------------------------------------- 
>
>
> Any help very much appreciated
>
> Thanks,
>
> Gerry
>
>
>
>

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: error: 'cit' was not declared in this scope
  2009-12-29 20:45 ` John S. Fine
@ 2009-12-30  3:49   ` Gerry Sweeney
  2009-12-30 13:51     ` Andrew Haley
  0 siblings, 1 reply; 8+ messages in thread
From: Gerry Sweeney @ 2009-12-30  3:49 UTC (permalink / raw)
  To: John S. Fine; +Cc: gcc-help

Hi John,

Thats perfect and solved my problem, thank you very much. I now have a 
better understanding of what the compiler is expecting.  The compiler could 
certinaly do with a more explicit error message in this scenario, perhaps 
something like:-

    test.cpp:30: error: The item base_type::const_iterator is not known as a 
type

certainly would have helped

I did not go with the second "using" option as I thought it was less 
readable than being explicit about what is being called - at least for me it 
worked better that way.

Regards,

Gerry

----- Original Message ----- 
From: "John S. Fine" <johnsfine@verizon.net>
To: "Gerry Sweeney" <gerry.sweeney@blueyonder.co.uk>
Cc: <gcc-help@gcc.gnu.org>
Sent: Tuesday, December 29, 2009 7:49 PM
Subject: Re: error: 'cit' was not declared in this scope


> You are focusing on the second error, but that was just a consequence of 
> the first.
>
> During the initial parsing, the compiler doesn't know that types from the 
> base class are types, because it doesn't know what the base class will be 
> until it has the template actuals.
>
> You can tell it that types are types using the typename keyword in each 
> place where you use them.
>
> I think that is a bad style, and it is better to bring such types into the 
> current class with a typedef as in
>
>       typedef std::map<Key, Value> base_type;
>       typedef typename base_type::const_iterator const_iterator;
> ...
>       const_iterator cit = base_type::find(key);
>
> But in similar style, I also think "using" is better than individual 
> overrides for functions that should be inherited from the base class:
>
>       typedef std::map<Key, Value> base_type;
>       typedef typename base_type::const_iterator const_iterator;
>       using base_type::find;
> ...
>       const_iterator cit = find(key);
>


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: error: 'cit' was not declared in this scope
  2009-12-30  3:49   ` Gerry Sweeney
@ 2009-12-30 13:51     ` Andrew Haley
  2009-12-30 23:59       ` John S. Fine
  0 siblings, 1 reply; 8+ messages in thread
From: Andrew Haley @ 2009-12-30 13:51 UTC (permalink / raw)
  To: gcc-help

On 12/30/2009 03:38 AM, Gerry Sweeney wrote:

> Thats perfect and solved my problem, thank you very much. I now have
> a better understanding of what the compiler is expecting.  The
> compiler could certinaly do with a more explicit error message in
> this scenario, perhaps something like:-
> 
>     test.cpp:30: error: The item base_type::const_iterator is not known as a  type 
> certainly would have helped

Sure, but gcc doesn't tell you that because gcc doesn't know because
the grammar is ambiguous.  This is really a bug in the language: its
grammar isn't context-free.

Andrew.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: error: 'cit' was not declared in this scope
  2009-12-30 13:51     ` Andrew Haley
@ 2009-12-30 23:59       ` John S. Fine
  2010-01-06 15:35         ` Ian Lance Taylor
  0 siblings, 1 reply; 8+ messages in thread
From: John S. Fine @ 2009-12-30 23:59 UTC (permalink / raw)
  To: Andrew Haley; +Cc: gcc-help

Andrew Haley wrote:
> On 12/30/2009 03:38 AM, Gerry Sweeney wrote:
>
>   
>> Thats perfect and solved my problem, thank you very much. I now have
>> a better understanding of what the compiler is expecting.  The
>> compiler could certinaly do with a more explicit error message in
>> this scenario, perhaps something like:-
>>
>>     test.cpp:30: error: The item base_type::const_iterator is not known as a  type 
>> certainly would have helped
>>     
>
> Sure, but gcc doesn't tell you that because gcc doesn't know because
> the grammar is ambiguous.  This is really a bug in the language: its
> grammar isn't context-free.
>
>   
Having written many parsers myself (though not for anything approaching 
the difficulty of parsing C++) I know how hard it is to get a parser to 
generate decent error messages.  But in this case the error message is 
particularly lame:

               base_type::const_iterator cit = base_type::find(key);
generates the error message
test.cpp:30: error: expected ';' before 'cit'

The parser can't know what base_type::const_iterator is supposed to be 
(but knows that it might find out later).  I think it knows that it 
doesn't know what cit is and that it won't find out later in any way 
that could make this sequence retroactively correct.  So I understand 
why it sees an error at/before cit.

I also understand that ';' is one of many tokens that could follow a 
name such as base_type::const_iterator in a way that allows the parser 
to expect that name will be a member of base_type and continue parsing.  
But ';' isn't the only token that would be valid there.  So at that 
point in the parser code, the author must have known it was at least an 
unhelpful error message.

I would think the parser should "know" that base_type::const_iterator is 
at the heart of the problem.  And it knows that 
base_type::const_iterator hasn't been declared yet, and the author of 
the parser should know that the fact that base_type::const_iterator can 
be parsed before it is declared is an error prone feature of the language.

So in my opinion, it should be possible to generate an error more like:
Parse error after 'base_type::const_iterator', which is not yet declared 
because 'base_type' depends on templating.

I agree with what I think Andrew said that the parser should not try to 
guess that base_type::const_iterator was intended to be a type.  But I 
think it can reasonably guess that base_type::const_iterator is the 
proximate cause of the error.
Once the user understands that the compiler doesn't think 
base_type::const_iterator has been declared yet, the user should not 
have much trouble understanding the actual problem.

The code I port to GCC has far more of exactly this bug than most 
programmers will ever see.  So I'm already past the point where it 
matters at all what the error message says.  I will recognize this bug 
from any error message that identifies the approximate location in the 
source.  But I think there are plenty of people who will be porting code 
where a better error message would make a big difference.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: error: 'cit' was not declared in this scope
  2009-12-30 23:59       ` John S. Fine
@ 2010-01-06 15:35         ` Ian Lance Taylor
  0 siblings, 0 replies; 8+ messages in thread
From: Ian Lance Taylor @ 2010-01-06 15:35 UTC (permalink / raw)
  To: John S. Fine; +Cc: gcc-help

"John S. Fine" <johnsfine@verizon.net> writes:

> Having written many parsers myself (though not for anything
> approaching the difficulty of parsing C++) I know how hard it is to
> get a parser to generate decent error messages.  But in this case the
> error message is particularly lame:

I would encourage you to file a bug report with a test case.  See
http://gcc.gnu.org/bugs/ .

Ian

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: error: 'cit' was not declared in this scope
  2009-12-29 17:30 ` Gerry Sweeney
@ 2009-12-29 18:11   ` Ian Lance Taylor
  0 siblings, 0 replies; 8+ messages in thread
From: Ian Lance Taylor @ 2009-12-29 18:11 UTC (permalink / raw)
  To: Gerry Sweeney; +Cc: gcc-help

"Gerry Sweeney" <gerry.sweeney@hornbill.com> writes:

> ****************************************
>
> IMPORTANT INFORMATION
> The information contained in this email or any of its attachments is confidential and is intended for the exclusive use of the individual or entity to whom it is addressed. It may not be disclosed to, copied, distributed or used by anyone else without our express permission. If you receive this communication in error please advise the sender immediately and delete it from your systems.  This email is not intended to and does not create legally binding commitments or obligations on behalf of Hornbill Systems which may only be created by hard copy writing signed by a director or other authorized officer.  Any opinions, conclusions and other information in this message that do not relate to the official business of Hornbill Systems Limited are unauthorized and neither given nor endorsed by it. Although Anti-Virus measures are used by Hornbill Systems it is the responsibility of the addressee to scan this email and any attachments for computer viruses or other defects. Hornbill Systems does not accept any liability for any loss or damage of any nature, however caused, which may result directly or indirectly from this email or any file attached.
>
> Hornbill Systems Limited. Registered Office: Ares, Odyssey Business Park, West End Road, Ruislip, HA4 6QD, United Kingdom. Registered in England Number: 3033585
>
> ****************************************

I started to write a reply to your message but then I saw this
disclaimer.  Disclaimers of this sort are inappropriate for a mailing
list like gcc-help which automatically creates a web archive of all
messages, and are against list policy (http://gcc.gnu.org/lists.html).
Please remove the disclaimer.  If your company policy does not permit
that, I suggest that you open a free web-based e-mail account at any
of various providers.

Ian

^ permalink raw reply	[flat|nested] 8+ messages in thread

* RE: error: 'cit' was not declared in this scope
       [not found] <E2A1DD3AE3471D42B24E218A48E0D89D0187585B@exch2.internal.hornbill.com>
@ 2009-12-29 17:30 ` Gerry Sweeney
  2009-12-29 18:11   ` Ian Lance Taylor
  0 siblings, 1 reply; 8+ messages in thread
From: Gerry Sweeney @ 2009-12-29 17:30 UTC (permalink / raw)
  To: gcc-help

Hi,

I am trying to port some code from VC9 to Linux using "gcc (Ubuntu 4.4.1-4ubuntu8) 4.4.1" and I am getting an error with GCC that I don't get when compiling under VC9. 

test.cpp: In member function 'const Value& enums_map<Key, Value>::operator[](const Key&) const':
test.cpp:30: error: expected ';' before 'cit'
test.cpp:31: error: 'cit' was not declared in this scope

The problem is I need to create a local variable of type <the base class>::const_iterator but I cant work out how I can do this. As I mentioned, the code below works when compiling under VC9 but not with g++. I can't work out how to solve this problem, could anyone help? This is the code sample (just compiling with "g++ test.cpp"

---------------------------------<snip>-------------------------------------
#include <stdio.h>
#include <string>
#include <iostream>
#include <tr1/regex>
#include <inttypes.h>
#include <stdarg.h>

#include <map>


// Just the std::map, plus a const version of operator[] which returns a const reference to a const member
template<typename Key, typename Value>
class enums_map : public std::map<Key, Value>
{
        typedef std::map<Key, Value> base_type;

public:
        enums_map()
                : default_value_()
        {
        }

        enums_map(const Value& default_value)
                : default_value_(default_value)
        {
        }

        const Value& operator[] (const Key& key) const
        {
                base_type::const_iterator cit = base_type::find(key);
                if (cit == base_type::end())
                        return default_value_;
                else
                        return cit->second;
        }

        using base_type::operator[];

private:
        const Value default_value_;
};
---------------------------------<snip>-------------------------------------

Any help very much appreciated

Thanks,

Gerry




****************************************

IMPORTANT INFORMATION
The information contained in this email or any of its attachments is confidential and is intended for the exclusive use of the individual or entity to whom it is addressed. It may not be disclosed to, copied, distributed or used by anyone else without our express permission. If you receive this communication in error please advise the sender immediately and delete it from your systems.  This email is not intended to and does not create legally binding commitments or obligations on behalf of Hornbill Systems which may only be created by hard copy writing signed by a director or other authorized officer.  Any opinions, conclusions and other information in this message that do not relate to the official business of Hornbill Systems Limited are unauthorized and neither given nor endorsed by it. Although Anti-Virus measures are used by Hornbill Systems it is the responsibility of the addressee to scan this email and any attachments for computer viruses or other defects. Hornbill Systems does not accept any liability for any loss or damage of any nature, however caused, which may result directly or indirectly from this email or any file attached.

Hornbill Systems Limited. Registered Office: Ares, Odyssey Business Park, West End Road, Ruislip, HA4 6QD, United Kingdom. Registered in England Number: 3033585

****************************************

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2010-01-06 15:35 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-12-29 19:49 error: 'cit' was not declared in this scope Gerry Sweeney
2009-12-29 20:45 ` John S. Fine
2009-12-30  3:49   ` Gerry Sweeney
2009-12-30 13:51     ` Andrew Haley
2009-12-30 23:59       ` John S. Fine
2010-01-06 15:35         ` Ian Lance Taylor
     [not found] <E2A1DD3AE3471D42B24E218A48E0D89D0187585B@exch2.internal.hornbill.com>
2009-12-29 17:30 ` Gerry Sweeney
2009-12-29 18:11   ` Ian Lance Taylor

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).