Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
Home
Discussion Groups
General
GeneralPortable MacsHardwareNetworking
Applications
Mac ApplicationsEudoraFirefox / MozillaInternet ExplorerOutlook ExpressMS OfficeEntourageExcelPowerPointWordVirtual PCMedia PlayerOther MS Products
Programming
Mac ProgrammingCodeWarriorPerl
Country Specific
Australian Mac GroupUK Mac Group

Mac Forum / Programming / CodeWarrior / January 2004



Tip: Looking for answers? Try searching our database.

C++ parsing problem

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Alexey Proskuryakov - 13 Jan 2004 14:30 GMT
Hi!

 I'm converting a project to CW 9, and have run into a problem with a piece
of code that was fine for CW 8.

 Here is a (minimized) code snippet that gives an error. As both CW 9 and
gcc dislike it in the same way, I suppose that it's my bug. So, why isn't
this proper C++, and is there a good workaround?

-------------------------------

#include <vector>
#include <utility>

struct C {
   
   int f(
       const std::vector< std::pair<int, int> > & inExtraHeaders =
           std::vector< std::pair<int, int> >()
   );

};

-------------------------------

Error   : ')' expected
SimpleAlert.cp line 8      std::vector< std::pair<int, int> >()

Error   : ';' expected
SimpleAlert.cp line 8      std::vector< std::pair<int, int> >()

Error   : illegal default argument(s)
SimpleAlert.cp line 8      std::vector< std::pair<int, int> >()

- WBR, Alexey Proskuryakov
MW Ron - 13 Jan 2004 15:52 GMT
>Hi!
>
[quoted text clipped - 29 lines]
>Error   : illegal default argument(s)
>SimpleAlert.cp line 8      std::vector< std::pair<int, int> >()

Hi,  This is documented in the 3.2 release notes:

---

*    Deferred parsing of default arguments in member functions is now
enabled by default
   (#pragma defer_defarg_parsing on). Note that some default expressions
with template
   argument list will now have to be parenthesized:

       template<typename T,typename U> struct X { T t; U u; };
       struct Y {
           void f(X<int,int> = X<int,int>());        //    error, not
accepted  with defer_defarg_parsing on
       };

   Fix:

       template<typename T,typename U> struct X { T t; U u; };
       struct Y {
           void f(X<int,int> = (X<int,int>()) );    //    OK if default
argument is parenthesized
       };

   See also core issue 325.  (copied below)

So we implemented the suggested solution for core issue 325:

> Suggested resolution:
>
[quoted text clipped - 4 lines]
> default argument expressions shall not require evaluation of a default
> argument of a function declared later in the class.

And you have to use:

#include <vector>
#include <utility>

struct C {
   
   int f(
       const std::vector< std::pair<int, int> > & inExtraHeaders
           = ( std::vector<  std::pair<int, int> >() )
   );

};

Ron

Signature

Metrowerks, maker of CodeWarrior   -  "Software Starts Here"  
Ron Liechty - MWRon@metrowerks.com - <http://www.metrowerks.com>

Alexey Proskuryakov - 14 Jan 2004 08:53 GMT
Hi!

 Thank you for the in-depth clarification and workaround. The workaround
suggested by Dave helps as well.

 However, I'm a bit confused about issue 325. Is it that I misinterpret the
suggested solution, or CW 9.1 actually doesn't implement it? The comma in
both my example and the one from release notes is very well bracketed (with
angle brackets), so it shouldn't mark an end of default argument expression.

 Of course, this issue is still in "open" state, so no means of handling it
can be formally correct, I guess :)

On 13.01.2004 18:52, in article
mwron-3F612A.10523813012004@enews.newsguy.com, "MW Ron"
<mwron@metrowerks.com> wrote:

> Hi,  This is documented in the 3.2 release notes:
>
[quoted text clipped - 32 lines]
>> default argument expressions shall not require evaluation of a default
>> argument of a function declared later in the class.

- WBR, Alexey Proskuryakov
MW Ron - 14 Jan 2004 15:21 GMT
>  Thank you for the in-depth clarification and workaround. The workaround
>suggested by Dave helps as well.
[quoted text clipped - 3 lines]
>both my example and the one from release notes is very well bracketed (with
>angle brackets), so it shouldn't mark an end of default argument expression.

Deferred parsing of default arguments in member functions is now
enabled by default, in CW 8.3 you'd have to specifically enable it.

Issue 325 is an issue in the Standards (default arguments) that is going
to be changed with this suggested resolution which we have adapted prior
to it being formally approved.

 Suggested resolution:

 Append the following text to 8.3.6  dcl.fct.default paragraph 8.
 The default argument expression of a member function declared
 in the class definition consists of the sequence of tokens up until
 the next non-parenthesized, non-bracketed comma or close
 parenthesis. Furthermore such default argument expressions shall
 not require evaluation of a default argument of a function declared
 later in the class.

Does that explain it better.

Ron

Signature

Metrowerks, maker of CodeWarrior   -  "Software Starts Here"  
Ron Liechty - MWRon@metrowerks.com - <http://www.metrowerks.com>

Alexey Proskuryakov - 15 Jan 2004 08:44 GMT
On 14.01.2004 18:21, in article
mwron-0D1D79.10215614012004@news.newsguy.com, "MW Ron"
<mwron@metrowerks.com> wrote:

> Deferred parsing of default arguments in member functions is now
> enabled by default, in CW 8.3 you'd have to specifically enable it.
[quoted text clipped - 14 lines]
>
> Does that explain it better.

 Please, consider the example from the 9.0 release notes:

// ----------------------
       template<typename T,typename U> struct X { T t; U u; };
       struct Y {
           void f(X<int,int> = X<int,int>());        //    error, not
accepted  with defer_defarg_parsing on
       };
// ----------------------

 Here, the default argument expression starts after the '=' sign and should
continue "up until the next non-parenthesized, non-bracketed comma or close
parenthesis". The next comma (between ints) is bracketed, so the default
argument continues until the next closing parenthesis, and should be
"X<int,int>()".

 So, although the standard doesn't require that this declaration is parsed
without error, the suggested solution makes it valid.

 Please also note that Comeau online compiler also thinks that this code is
OK. I have previously reported that gcc behaves like CW 9, but have since
found that they have a bug filed against this, and just don't want to change
anything until the issue is formally closed by the comittee.

 This is what makes me believe that CW 9 doesn't implement the suggested
solution to issue 325 (but breaks compatibility with CW 8 in default mode
for no apparent reason).

- WBR, Alexey Proskuryakov
MW Ron - 15 Jan 2004 14:49 GMT
>On 14.01.2004 18:21, in article
>mwron-0D1D79.10215614012004@news.newsguy.com, "MW Ron"
[quoted text clipped - 42 lines]
>found that they have a bug filed against this, and just don't want to change
>anything until the issue is formally closed by the comittee.

Right as I understand we are ahead of the loop not behind the loop on
this one.  I may not fully understand this though.

>  This is what makes me believe that CW 9 doesn't implement the suggested
>solution to issue 325 (but breaks compatibility with CW 8 in default mode
>for no apparent reason).

You could be right trying to read the standards often gives me a
headache let alone the committee actions.     Andreas is the one that
wrote up the reply and he believes he is doing the right thing.  Send me
an e-mail and I'll forward it on to him,  he is open and will listen and
correct any misunderstandings he or explain why he went this way.  If we
are wrong we will correct it.

Ron

Signature

Metrowerks, maker of CodeWarrior   -  "Software Starts Here"  
Ron Liechty - MWRon@metrowerks.com - <http://www.metrowerks.com>

MW Ron - 15 Jan 2004 17:48 GMT
> Please, consider the example from the 9.0 release notes:
>
[quoted text clipped - 23 lines]
>solution to issue 325 (but breaks compatibility with CW 8 in default mode
>for no apparent reason).

First off,  if you want the compatibility with CW 8.3  you can just use
a pragma

#pragma defer_defarg_parsing off

your original version compiles then.

Andreas's reply to your comments was...

The comma between int,int is not [bracketed] and not (parenthesized), so
I think my solution is correct.

The core defect and resolution was actually reported by one of the GCC
authors.

There are good reasons for this change, the C++ grammar is highly
ambiguous and some (other) examples cannot be properly parsed without
this change.

Ron

Signature

Metrowerks, maker of CodeWarrior   -  "Software Starts Here"  
Ron Liechty - MWRon@metrowerks.com - <http://www.metrowerks.com>

David Phillip Oster - 13 Jan 2004 15:56 GMT
> -------------------------------
>
[quoted text clipped - 11 lines]
>
> -------------------------------

If you replace the vector type by V, you get:

typedef std::vector< std::pair<int, int> > V;

struct C {
  int f(const V& inExtraHeaders = V());
};

Clearly, after the equal sign should be a value, not an extern
function declaration (which is what V() is.)

struct C {
private:
  static const V v;
public:
  int f(const V& inExtraHeaders = v);
};
Dave Baum - 13 Jan 2004 16:37 GMT
> If you replace the vector type by V, you get:
>
[quoted text clipped - 6 lines]
> Clearly, after the equal sign should be a value, not an extern
> function declaration (which is what V() is.)

I believe that in this context, V() is a call to the default constructor
for type V, and is valid C++.  It should result in a new local instance
of V being constructed (and destructed after f() exits).

Dave
David Phillip Oster - 13 Jan 2004 18:06 GMT
> > If you replace the vector type by V, you get:
> >
[quoted text clipped - 10 lines]
> for type V, and is valid C++.  It should result in a new local instance
> of V being constructed (and destructed after f() exits).

You are right. I'd gotten confused with:

int f(){
  V  v();  // declare "v" to be an extern function, returning a V.
  V  v1;   // declares a variable of type V, calling no-arg constructor.
}
Dave Baum - 13 Jan 2004 16:17 GMT
> Hi!
>
[quoted text clipped - 4 lines]
> gcc dislike it in the same way, I suppose that it's my bug. So, why isn't
> this proper C++, and is there a good workaround?

I'm not sure why it isn't proper C++.  Interestingly enough, if you make
a typedef for pair<int,int> then gcc seems to like it better.  Would
this be an acceptable workaround?  

-------------------------------
#include <vector>
#include <utility>

typedef std::pair<int,int> P;

struct C {

   int f(
       const std::vector< P > & inExtraHeaders =
           std::vector< P >()
   );

};

------

I don't have CW9 so I couldn't verify with that compiler.

Dave

> -------------------------------
>
[quoted text clipped - 22 lines]
>
> - WBR, Alexey Proskuryakov
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2009 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.