Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Why does 'int f(int(i));' declares a function?

3 views
Skip to first unread message

Daniel Frey

unread,
Nov 8, 2000, 3:00:00 AM11/8/00
to
Hi,

this is the first time I'm posting to comp.std.c++, so please excuse if
this is the wrong newsgroup or the wrong way :)

the standard says that 'int f(int(i));' declares a function 'f' that
expects an 'int' and return 'int'. I wonder if there is any specific
reason for this. I discussed this topic with some folks on comp.lang.c++
but the only explanation they had to offer was "historical reasons". Jim
Hyslop told me that the standard says:

--- snipp ---

The standard (8.2/1) provides a good example, including a couple of ways
of re-phrasing your declaration to avoid ambiguity:

[Example:
struct S {
S(int);
};

void foo(double a)
{
S w(int(a)); // function declaration
S x(int()); // function declaration
S y((int)a); // object declaration
S z = int(a); // object declaration
}
end example]

--- snapp ---

I understand that if 'int f(int(i));' is read as a C statement, a
C-compiler has no choice - it has to be a function declaration. This was
made possible by a late C-standard change called 'function-style-cast'.
I was further told that C++ tries to be compatible to this and therefore
it is a function declaration in C++.

If this is the only reason, I'd suggest to rethink it. I never saw
anyone writing 'int f(int(i));' when he wants to declare a function.
People write 'int f(int i);' or just 'int f(int);'. I'd like to see the
following change:

void foo(double a)
{
S u(int a); // function declaration
S v(int); // function declaration
S w(int(a)); // object declaration
S x(int()); // object declaration
S y((int)a); // object declaration
S z = int(a); // object declaration
}

This will break compatibility to C, but it will increase readability in
C++. Today, people write 'int f((int(i)));' if they want declare an
object and this looks odd. It just feels unnatural. (I don't know if
this is a valid reason, but I think a language should be as intuitive as
possible).

There is another reason: If you replace 'int' by a class 'T', thing get
even more complicated. Consider the following:

template< typename T > class A
{
T t;
}

't' is initialized with it's default constructor when it is another
class, but it is uninitialized when T = int. If I want to have an
initialized object in every case, I could write

T t = T();

but this requires that T() has a non-explicit default constructor, which
weakens the usability of 'explicit'. So I have to use the unintuitive

T t((T()));

All in all: I see some disadvantages in the current definition and one
(IMHO minor) disadvantage in a change (breaking compatibility in a case
that's AFAIK almost never used). Now my question is: Are there any other
reasons why the standard is defined to take 'int f(int(i));' as a
function declaration? Is it possible to change it without breaking
something else?

Regards, Daniel

--
Daniel Frey

aixigo AG - Financial Research and Education
Hammerweg 4, 52074 Aachen, Germany
Tel: +49 (0)241 96106-17, Fax: +49 (0)241 96106-20
EMail: D.F...@aixigo.de

---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std...@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
[ Note that the FAQ URL has changed! Please update your bookmarks. ]


Michael Spencer

unread,
Nov 9, 2000, 3:00:00 AM11/9/00
to
Daniel Frey wrote:
>
> If this is the only reason, I'd suggest to rethink it. I never saw
> anyone writing 'int f(int(i));' when he wants to declare a function.
> People write 'int f(int i);' or just 'int f(int);'. I'd like to see the
> following change:
>
> void foo(double a)
> {
> S u(int a); // function declaration
> S v(int); // function declaration
> S w(int(a)); // object declaration
> S x(int()); // object declaration
> S y((int)a); // object declaration
> S z = int(a); // object declaration
> }
>
Yes, I agree, the syntax is slightly confusing. However, the rule
used to resolve expr/decl ambiguities is actually very simple: try
declarations first. This would be a special case.

But OK, let's try it. Suppose you consider function style casts
first. Would you then say the following is an object declaration?

S s (int (* a));

If yes, then what about

S s (int (* a) ());

Here, from a syntax point of view, 'int (* a) ()' is a valid
expression,

postfix-expression:
postfix-expression ( expression-listopt )
simple-type-specifier ( expression-listopt )

But in this context, obviously, it should not be considered an
expression. So where then do you draw the line? Should your
parser disambiguate in this order:

1) trivial function style cast expression

2) parameter declaration

3) non-trivial function style cast expression

I think it would just make things more complicated.

Another point, consider:

S s (int (a), int (b), int c);

According to you suggestion, 'int (a)' and 'int (b)' would be
parsed first as expressions. 'int c', of course, would change this,
they'd have to be declarations. However, C++ parsers (in my experience),
have to evaluate expressions as they are parsed (to handle things like
'a.f<'), but, here, you don't want to evaluate 'int (a)' and 'int (b)'
because your parser is still guessing.

Really, there's a very clean design underneath :)

Mike

James...@dresdner-bank.com

unread,
Nov 9, 2000, 3:00:00 AM11/9/00
to
In article <3A091E43...@aixigo.de>,
Daniel Frey <d.f...@aixigo.de> wrote:

> the standard says that 'int f(int(i));' declares a function 'f' that
> expects an 'int' and return 'int'. I wonder if there is any specific
> reason for this.

There's a very good reason. For historical reasons, C++ has any
number of cases where a sequence of tokens could be interpreted as
either a declaration or an expression. The simplest, most
understandable rule is to choose one or the other, systematically.
The choice was declaration, probably because it is generally more
difficult to rephrase a declaration so that it cannot be an expression
that otherwise. Most things that look like declarations are.

The alternative would be a complicated set of rules, in which
something that could be either would sometimes be one, sometimes the
other. In the end, despite the problems, I think we have the lesser
of two evils.

--
James Kanze mailto:ka...@gabi-soft.de
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
Ziegelhüttenweg 17a, 60598 Frankfurt, Germany Tel. +49(069)63198627


Sent via Deja.com http://www.deja.com/
Before you buy.

Jim Hyslop

unread,
Nov 9, 2000, 3:00:00 AM11/9/00
to
In article <3A091E43...@aixigo.de>,
Daniel Frey <d.f...@aixigo.de> wrote:
> Hi,
[snip]

> Consider the following:
>
> template< typename T > class A
> {
> T t;
> }
>
> 't' is initialized with it's default constructor when it is another
> class, but it is uninitialized when T = int. If I want to have an
> initialized object in every case, I could write
>
> T t = T();
>
> but this requires that T() has a non-explicit default constructor,
> which
> weakens the usability of 'explicit'.
I don't follow you on this - how do you figure a non-explicit default
ctor is required? "T()" is an explicit call to a ctor, so the following
should work:

class T
{
public:
explicit T() {}
};

template< typename T >
void f()
{
T t=T();
}

int main()
{
T t = T();
f<T>();
}

Or was there some slightly different example you had in mind?

--
Jim
This message was posted using plain text only. Any hyperlinks you may
see were added by other parties without my permission.
I do not endorse any products or services that may be hyperlinked to
this message.

Jim Hyslop

unread,
Nov 9, 2000, 3:00:00 AM11/9/00
to
In article <3A091E43...@aixigo.de>,
Daniel Frey <d.f...@aixigo.de> wrote:
> Hi,
[snip]
> I understand that if 'int f(int(i));' is read as a C statement, a
> C-compiler has no choice - it has to be a function declaration. This
> was
> made possible by a late C-standard change called
> 'function-style-cast'.
I presume you meant "C++ standard change" here?

BTW, just as some background here - Daniel and I discussed this issue a
bit in comp.lang.c++ forum. I suggested that the reason 'int f(int(i));'
was read as a declaration was because of backwards compatibility with C.
I also suggested that he post the question here, to see if anyone could
explain *why* the standard prefers a function declaration over a
variable definition.

[snip]
> If this [backwards compatibility] is the only reason, I'd suggest to


> rethink it. I never saw
> anyone writing 'int f(int(i));' when he wants to declare a function.
> People write 'int f(int i);' or just 'int f(int);'. I'd like to see
the
> following change:
>
> void foo(double a)
> {
> S u(int a); // function declaration
> S v(int); // function declaration
> S w(int(a)); // object declaration
> S x(int()); // object declaration
> S y((int)a); // object declaration
> S z = int(a); // object declaration
> }
>

> This will break compatibility to C, but it will increase readability
> in
> C++.

Specifically, this means that the statement:

int f( int(i) );

would mean 'f' is a function in C, but 'f' is an int in C++. So the
question boils down to: are we ready to consider widening the gap
between C and C++?

Greg Comeau

unread,
Nov 9, 2000, 3:00:00 AM11/9/00
to
In article <8uejp5$tv$1...@nnrp1.deja.com>,

Jim Hyslop <jim.h...@leitch.com> wrote:
>Specifically, this means that the statement:
>
>int f( int(i) );
>
>would mean 'f' is a function in C, but 'f' is an int in C++. So the
>question boils down to: are we ready to consider widening the gap
>between C and C++?

Hmm, I thought there were specific words in C++ making this
a function?

- Greg
--
Comeau Computing / Comeau C/C++ "so close" 4.2.44 betas NOW AVAILABLE
TRY Comeau C++ ONLINE at http://www.comeaucomputing.com/tryitout
Email: com...@comeaucomputing.com / WEB: http://www.comeaucomputing.com

Dennis Yelle

unread,
Nov 9, 2000, 3:00:00 AM11/9/00
to
James...@dresdner-bank.com wrote:
>
> In article <3A091E43...@aixigo.de>,
> Daniel Frey <d.f...@aixigo.de> wrote:
>
> > the standard says that 'int f(int(i));' declares a function 'f' that
> > expects an 'int' and return 'int'. I wonder if there is any specific
> > reason for this.
>
> There's a very good reason. For historical reasons, C++ has any
> number of cases where a sequence of tokens could be interpreted as
> either a declaration or an expression. The simplest, most
> understandable rule is to choose one or the other, systematically.
> The choice was declaration, probably because it is generally more
> difficult to rephrase a declaration so that it cannot be an expression
> that otherwise. Most things that look like declarations are.
>
> The alternative would be a complicated set of rules, in which
> something that could be either would sometimes be one, sometimes the
> other. In the end, despite the problems, I think we have the lesser
> of two evils.

That assumes that there are only two choices.
We could instead decide that ambiguous things are errors.
That would be more consistent with the other language rules.
If we need to invent 'declare' and 'evaluate' keywords to disambiguate
some things, than so be it.

Dennis Yelle
--
I am a computer programmer and I am looking for a job.
There is a link to my resume here:
http://table.jps.net/~vert/

Daniel Frey

unread,
Nov 10, 2000, 3:00:00 AM11/10/00
to
Michael Spencer wrote:

> Yes, I agree, the syntax is slightly confusing. However, the rule
> used to resolve expr/decl ambiguities is actually very simple: try
> declarations first. This would be a special case.

And that rules is used. But is it a function declaration or a variable
declaration? Whenever an expression could be both, currently function
declarations are prefered. I was just wondering if there are any
*ambiguous* expressions that you *want* to be a function declaration. I
think that

T x;

and

T(x);

are just two totally different things.

> But OK, let's try it. Suppose you consider function style casts
> first. Would you then say the following is an object declaration?
>
> S s (int (* a));

In my eyes, this would be a variable declaration, read like this:

S s( int( *a ) );

> If yes, then what about
>
> S s (int (* a) ());

Good point. If 'a' if a pointer to a function, (*a)() would be a call
that function, right? But the result (I call the resulting object 'o')
leads to

S s( int o );

This cannot be a variable declaration. Therefore, the complete
expression has to be a function declaration. To make it a variable
declaration, you'd write:

S s( int( (*a)() ) );

> Here, from a syntax point of view, 'int (* a) ()' is a valid
> expression,
>
> postfix-expression:
> postfix-expression ( expression-listopt )
> simple-type-specifier ( expression-listopt )

The question is, if the grammar is what it should be. :)

> But in this context, obviously, it should not be considered an
> expression. So where then do you draw the line? Should your
> parser disambiguate in this order:
>
> 1) trivial function style cast expression
>
> 2) parameter declaration
>
> 3) non-trivial function style cast expression
>
> I think it would just make things more complicated.

I agree that there shouldn't be any complicate rules. I don't ask to
change the standard just because I want it. I was only 'thinking' about
the consequences when I change a simple rule to another simple rule.
Only ambiguous cases change from "preferably function declaration" to
"preferably variable declaration". I think that there are reasons why it
wasn't defined that way, as the people who invented C++ are usually ways
better than I am. But I'd like to understand their reasons.

> Another point, consider:
>
> S s (int (a), int (b), int c);
>
> According to you suggestion, 'int (a)' and 'int (b)' would be
> parsed first as expressions. 'int c', of course, would change this,
> they'd have to be declarations. However, C++ parsers (in my experience),
> have to evaluate expressions as they are parsed (to handle things like
> 'a.f<'), but, here, you don't want to evaluate 'int (a)' and 'int (b)'
> because your parser is still guessing.

Hm. Consider:

int f( int(i) ); // function declaration
int g( (int(i)) ); // object declaration

is this so different than your example? The compiler has to read the
whole expression to decide what 'f' or 'g' should be.

> Really, there's a very clean design underneath :)

I hope so :) Believe me, I don't want any change if it leads to more
complexity. C++ is complex enough, I just hope that a change like the
one I think about will lead to easier code.

BTW: Please forget the 'explicit'-stuff of my original post. It showed
that the problem I was seeing was caused by something else. In fact, I
used the STL and there was a case where I was forced to remove the
'explicit'-keyword for a class in order to use it in a container. Since
I'm not sure whether this is a bug in my STL or 'not supported' or it's
just me who hasn't understood STL and what the standard says about this,
I will investigate a bit further and ask the question on comp.lang.c++
first.

Regards, Daniel

--
Daniel Frey

aixigo AG - Financial Research and Education
Hammerweg 4, 52074 Aachen, Germany
Tel: +49 (0)241 96106-17, Fax: +49 (0)241 96106-20
EMail: D.F...@aixigo.de

---

Balog Pal (mh)

unread,
Nov 10, 2000, 3:00:00 AM11/10/00
to
Dennis Yelle wrote in message <3A0B0352...@jps.net>...

>> > the standard says that 'int f(int(i));' declares a function 'f' that
>> > expects an 'int' and return 'int'. I wonder if there is any specific
>> > reason for this.


I'd expect at least a high level warning from the compiler if a function
declaration is found inside a function body. Anyone still declares function
protos inside function bodies? All chances say something else were intended.

Paul

James...@dresdner-bank.com

unread,
Nov 10, 2000, 3:00:00 AM11/10/00
to
In article <3A0B0352...@jps.net>,

Dennis Yelle <denn...@jps.net> wrote:
> James...@dresdner-bank.com wrote:
> >
> > In article <3A091E43...@aixigo.de>,
> > Daniel Frey <d.f...@aixigo.de> wrote:

> > > the standard says that 'int f(int(i));' declares a function 'f'
> > > that expects an 'int' and return 'int'. I wonder if there is any
> > > specific reason for this.

> > There's a very good reason. For historical reasons, C++ has any


> > number of cases where a sequence of tokens could be interpreted as
> > either a declaration or an expression. The simplest, most
> > understandable rule is to choose one or the other, systematically.
> > The choice was declaration, probably because it is generally more
> > difficult to rephrase a declaration so that it cannot be an
> > expression that otherwise. Most things that look like
> > declarations are.

> > The alternative would be a complicated set of rules, in which
> > something that could be either would sometimes be one, sometimes
> > the other. In the end, despite the problems, I think we have the
> > lesser of two evils.

> That assumes that there are only two choices. We could instead
> decide that ambiguous things are errors. That would be more
> consistent with the other language rules. If we need to invent
> 'declare' and 'evaluate' keywords to disambiguate some things, than
> so be it.

I don't have any good example at hand, but I think that there are some
declarations which cannot be written in a way that cannot also be
interpreted as expressions.

--
James Kanze mailto:ka...@gabi-soft.de
Conseils en informatique orientée objet/

Beratung in objekt orientierter Datenverarbeitung


Ziegelhüttenweg 17a, 60598 Frankfurt, Germany Tel. +49(069)63198627

Sent via Deja.com http://www.deja.com/
Before you buy.

---

w...@fastdial.net

unread,
Nov 10, 2000, 3:00:00 AM11/10/00
to
In article <3A0BCF87...@aixigo.de>,

Daniel Frey <d.f...@aixigo.de> wrote:
> Michael Spencer wrote:
>
> > Yes, I agree, the syntax is slightly confusing. However, the rule
> > used to resolve expr/decl ambiguities is actually very simple: try
> > declarations first. This would be a special case.
>
> And that rules is used. But is it a function declaration or a variable
> declaration? Whenever an expression could be both, currently function
> declarations are prefered.

It's a recursive rule. The reason

int f(int(a));

is parsed as a function declaration is because "int(a)" could
be either a declaration or an expression, and the declaration
is preferred. That makes it a function declaration. To make
it be a variable declaration, you would have to treat "int(a)"
as an expression, which breaks the simple rule that "if it can
be a declaration, it is a declaration."

--
William M. Miller, w...@fastdial.net
Vignette Corporation (www.vignette.com)

Michael Spencer

unread,
Nov 10, 2000, 8:54:30 PM11/10/00
to
Daniel Frey wrote:
>
> Michael Spencer wrote:
>
> > Yes, I agree, the syntax is slightly confusing. However, the rule
> > used to resolve expr/decl ambiguities is actually very simple: try
> > declarations first. This would be a special case.
>
> And that rules is used. But is it a function declaration or a variable
> declaration? Whenever an expression could be both, currently function
> declarations are prefered. I was just wondering if there are any
> *ambiguous* expressions that you *want* to be a function declaration. I
> think that
>
> T x;
>
> and
>
> T(x);
>
> are just two totally different things.

They are actually the same thing. If it helps, try looking at it from
a grammar point of view, you'll see the parenthesis around the
declarator (the declarator is 'x') are just redundant.

Just so we have a context, suppose 'declaration' is

declaration:
type-name declarator ;

And from the Standard, 'declarator' is

declarator:
direct-declarator
ptr-operator declarator

direct-declarator:
declarator-id
direct-declarator ( parameter-declaration-clause ) cv-qualifier-seq-opt exception-specification-opt
direct-declarator [ constant-expression-opt ]
( declarator )

ptr-operator:
* cv-qualifier-seq-opt
&
::-opt nested-name-specifier * cv-qualifier-seq-opt

(You can think of 'declarator-id' as any name.)

The last rule of 'direct-declarator' says a declarator can be nested
inside parenthesis. So if you want, you could declare a function like

int ((f) (int i));

This works because 'f' and '(f)(int i)' are both declarators.

But the parenthesis are really there so that you can create a
direct-declarator that is a pointer, like

int (* f) ();

Without them, you'd not have a pointer to function.

But, sometimes the (not so) redundant set of parenthesis are really
needed. Look at

class B { };
B f ();
namespace N
{
void f ();
class A
{
friend B (::f) ();
};
}

Without the parenthesis around '::f' your compiler will correctly look
for 'B::f', which doesn't exist. But you need the '::' to refer to
'f' in the global scope. So you have to use the parenthesis.
Hmm ... this is a test of your compiler! g++ says 'parse error before `)''.
Opps, aCC doesn't compile it either! :) But
http://www.comeaucomputing.com/tryitout correctly compiles it.

> > If yes, then what about
> >
> > S s (int (* a) ());
>
> Good point. If 'a' if a pointer to a function, (*a)() would be a call
> that function, right? But the result (I call the resulting object 'o')
> leads to
>
> S s( int o );

Nope! :) 'int (* a) ()' as an expression binds like '(int (* a)) ()'.

postfix-expression:
postfix-expression ( expression-list-opt )
simple-type-specifier ( expression-list-opt )

Left to right, 'int (* a)' becomes a postfix-expression, which is then
followed by an (empty) argument list.

> Hm. Consider:
>
> int f( int(i) ); // function declaration
> int g( (int(i)) ); // object declaration
>
> is this so different than your example? The compiler has to read the
> whole expression to decide what 'f' or 'g' should be.

Yes, but by the time '(int(i))' is parsed as an expression, it will
never be anything else (since it's the last option). So the parser is
free to evaluate it as it is parsed (meaning evaluate it's type) and
give errors if it is not valid.

For example, a backtracking parser, when it sees the first '(', might
try '(int(i))' as a declaration. This will fail, so it'll backtrack
and try it as an expression. As the last option. But this is more
of implementation reason not to change things.

Hope this helps :)

Mike

Valentin Bonnard

unread,
Nov 10, 2000, 10:54:06 PM11/10/00
to
> Daniel Frey <d.f...@aixigo.de> wrote:
>> Michael Spencer wrote:
>>
>> > Yes, I agree, the syntax is slightly confusing. However, the rule
>> > used to resolve expr/decl ambiguities is actually very simple: try
>> > declarations first. This would be a special case.
>>
>> And that rules is used. But is it a function declaration or a variable
>> declaration? Whenever an expression could be both, currently function
>> declarations are prefered.
>
> It's a recursive rule.

No.

> The reason
>
> int f(int(a));
>
> is parsed as a function declaration is because "int(a)" could
> be either a declaration or an expression, and the declaration
> is preferred.

A funny way to see things in some cases (like this one),
but it is wrong.

--

Valentin Bonnard

Valentin Bonnard

unread,
Nov 11, 2000, 3:00:00 AM11/11/00
to
James Kanze wrote:

> I don't have any good example at hand, but I think that there are some
> declarations which cannot be written in a way that cannot also be
> interpreted as expressions.

A declaration has the form (simplified):

type declarator;

In order to parse as an expression, it has to be a functionnal cast:

type (expression);

and the declaration has to be

type (declarator);

Why can't you remove the parentheses arround the declaration ?

Alexandre Oliva

unread,
Nov 11, 2000, 3:00:00 AM11/11/00
to
On Nov 10, 2000, Daniel Frey <d.f...@aixigo.de> wrote:

> Michael Spencer wrote:
>> Yes, I agree, the syntax is slightly confusing. However, the rule
>> used to resolve expr/decl ambiguities is actually very simple: try
>> declarations first. This would be a special case.

> And that rules is used. But is it a function declaration or a variable
> declaration? Whenever an expression could be both, currently function
> declarations are prefered.

[...]


> I just hope that a change like the
> one I think about will lead to easier code.

I like to believe the rules have been set such that it's more likely
to get a diagnostic when the parse is not the one that was meant. If
the rules were the other way round, there was a risk that what you
intended to be a declaration end up being parsed as the construction
of a temporary, and that further references to the name that should
have been declared end up being resolved to other declarations in
outer scopes. I'm not sure this also applies to the case of
preferring function declarations over object declarations, but it
seems to me that the types of functions for which declarations are
ambiguous in the grammar are quite unusual, so you're likely to get
diagnostics when that's not what you meant. But maybe that would also
be the case should an object declaration be preferred.

--
Alexandre Oliva Enjoy Guarana', see http://www.ic.unicamp.br/~oliva/
Red Hat GCC Developer aoliva@{cygnus.com, redhat.com}
CS PhD student at IC-Unicamp oliva@{lsd.ic.unicamp.br, gnu.org}
Free Software Evangelist *Please* write to mailing lists, not to me

James...@dresdner-bank.com

unread,
Nov 13, 2000, 3:00:00 AM11/13/00
to
In article <8uig42$27s5$2...@nef.ens.fr>,

"Valentin Bonnard" <Valentin...@free.fr> wrote:
> James Kanze wrote:

> > I don't have any good example at hand, but I think that there are
> > some declarations which cannot be written in a way that cannot
> > also be interpreted as expressions.

> A declaration has the form (simplified):

> type declarator;

> In order to parse as an expression, it has to be a functionnal cast:

> type (expression);

> and the declaration has to be

> type (declarator);

> Why can't you remove the parentheses arround the declaration ?

The problem is more subtle. Something like type (expression)
more_stuff can also be parsed as an expression. And you can get
similar cases for declarations, where you need the paranthese for
precedence reasons. What should the following mean:

struct A
{
A( int ) ;
int operator[]( int ) ;
} ;

static int const x = 10 ;
A (*p)[x] ;

It's ambiguous, so it is interpreted as a declaration of a pointer to
10 A. It's easy to make it an expression:

(A (*p))[ x ] ;
or
(A)( *p )[ x ] ;

Suppose the initial were interpreted as an expression. How would you
write the declaration?

--
James Kanze mailto:ka...@gabi-soft.de
Conseils en informatique orientée objet/

Beratung in objektorientierter Datenverarbeitung


Ziegelhüttenweg 17a, 60598 Frankfurt, Germany Tel. +49(069)63198627

Sent via Deja.com http://www.deja.com/
Before you buy.

---

w...@fastdial.net

unread,
Nov 13, 2000, 3:00:00 AM11/13/00
to
In article <8uifou$27s5$1...@nef.ens.fr>,

"Valentin Bonnard" <Valentin...@free.fr> wrote:
> w...@fastdial.net wrote:
> > In article <3A0BCF87...@aixigo.de>,
> > Daniel Frey <d.f...@aixigo.de> wrote:
> >> Michael Spencer wrote:
> >>
> >> > Yes, I agree, the syntax is slightly confusing. However, the
rule
> >> > used to resolve expr/decl ambiguities is actually very simple:
try
> >> > declarations first. This would be a special case.
> >>
> >> And that rules is used. But is it a function declaration or a
variable
> >> declaration? Whenever an expression could be both, currently
function
> >> declarations are prefered.
> >
> > It's a recursive rule.
>
> No.
>
> > The reason
> >
> > int f(int(a));
> >
> > is parsed as a function declaration is because "int(a)" could
> > be either a declaration or an expression, and the declaration
> > is preferred.
>
> A funny way to see things in some cases (like this one),
> but it is wrong.

That's what 8.2p1 is all about: "the resolution is to consider
any construct that could possibly be a declaration a declaration."
The "construct" in this case is "int(a)".

As for the recursiveness of the rule, you are right that there
is no formal recursion from the statement-level ambiguity
resolution described in 6.8 to the intra-declaration ambiguity
resolution described in 8.2. I was intent on pointing out that
the same rule the poster had quoted regarding the
statement-level ambiguity resolution is the reason for parsing
the "int(a)" as a parameter declaration instead of an expression.
I should perhaps have been more precise in my terminology in
doing so.

However, the rule _is_ recursive in the context of intra-
declaration ambiguity resolution. For instance,

int f(int(int(int(3))));

declares an integer object initialized to the value "3", while

int f(int(int(int(a))));

declares a function whose parameter is a pointer to a function
whose parameter is a pointer to a function whose parameter is
an integer (after the function to pointer-to-function parameter
type adjustment). The difference is that "int(3)" can only be
interpreted as an expression, while "int(a)" can be interpreted
as a declaration. Making the determination of whether "f" is
an object or a function requires a 3-deep recursive application
of the rule, once for each "int(...)".

--
William M. Miller, w...@fastdial.net
Vignette Corporation (www.vignette.com)

Sent via Deja.com http://www.deja.com/
Before you buy.

---

Dennis Yelle

unread,
Nov 13, 2000, 3:00:00 AM11/13/00
to
James...@dresdner-bank.com wrote:
[...]

> The problem is more subtle. Something like type (expression)
> more_stuff can also be parsed as an expression. And you can get
> similar cases for declarations, where you need the paranthese for
> precedence reasons. What should the following mean:
>
> struct A
> {
> A( int ) ;
> int operator[]( int ) ;
> } ;
>
> static int const x = 10 ;
> A (*p)[x] ;
>
> It's ambiguous, so it is interpreted as a declaration of a pointer to
> 10 A. It's easy to make it an expression:
>
> (A (*p))[ x ] ;
> or
> (A)( *p )[ x ] ;
>
> Suppose the initial were interpreted as an expression. How would you
> write the declaration?

var A (*p)[x];

var would be legal any place const is legal,
but var means "not const".

Dennis Yelle
--
I am a computer programmer and I am looking for a job.
There is a link to my resume here:
http://table.jps.net/~vert/

---

Valentin Bonnard

unread,
Nov 14, 2000, 3:00:00 AM11/14/00
to
James...@dresdner-bank.com wrote:
> In article <8uig42$27s5$2...@nef.ens.fr>,

> "Valentin Bonnard" <Valentin...@free.fr> wrote:
>> James Kanze wrote:
>
>> > I don't have any good example at hand, but I think that there are
>> > some declarations which cannot be written in a way that cannot
>> > also be interpreted as expressions.

> The problem is more subtle.

That's right !

> Something like type (expression)
> more_stuff can also be parsed as an expression. And you can get
> similar cases for declarations, where you need the paranthese for
> precedence reasons. What should the following mean:
>
> struct A
> {
> A( int ) ;
> int operator[]( int ) ;
> } ;
>
> static int const x = 10 ;
> A (*p)[x] ;
>
> It's ambiguous, so it is interpreted as a declaration of a pointer to
> 10 A. It's easy to make it an expression:
>
> (A (*p))[ x ] ;

> Suppose the initial were interpreted as an expression. How would you
> write the declaration?

struct A (*p) [x];

--

Valentin Bonnard

Jim Hyslop

unread,
Nov 14, 2000, 3:00:00 AM11/14/00
to
In article <8uor33$p9b$1...@nnrp1.deja.com>,
w...@fastdial.net wrote:
[snip]

> That's what 8.2p1 is all about: "the resolution is to consider
> any construct that could possibly be a declaration a declaration."
> The "construct" in this case is "int(a)".
Yes, we all understand that, but the point of this thread is: *why* does
the rule prefer a declaration? Why not go the opposite, which is more
intuitive in many cases?

--
Jim
This message was posted using plain text only. Any hyperlinks you may
see were added by other parties without my permission.
I do not endorse any products or services that may be hyperlinked to
this message.

Sent via Deja.com http://www.deja.com/
Before you buy.

---

w...@fastdial.net

unread,
Nov 14, 2000, 3:00:00 AM11/14/00
to
In article <8urof1$67e$1...@nnrp1.deja.com>,

Jim Hyslop <jim.h...@leitch.com> wrote:
> In article <8uor33$p9b$1...@nnrp1.deja.com>,
> w...@fastdial.net wrote:
> [snip]
> > That's what 8.2p1 is all about: "the resolution is to consider
> > any construct that could possibly be a declaration a declaration."
> > The "construct" in this case is "int(a)".
> Yes, we all understand that,

Well, "all" is not quite accurate -- my post was in response to
Valentin Bonnard, who had labeled this interpretation "a funny
way to see things... but it is wrong."

> but the point of this thread is: *why* does
> the rule prefer a declaration? Why not go the opposite, which is more
> intuitive in many cases?

I'm speculating, but I would think one of the primary reasons
for the choice was C compatibility. The function-style cast,
which is the cause of the ambiguity, was a C++ innovation.
Choosing declarations over expressions meant that C code would
have the same meaning in C++. Choosing expressions over
declarations would have been a "gratuitous incompatibility"
with C. (Remember, the watchword in those days was "as close
as possible to C -- but no closer." Differences from C needed
to be very well-motivated.)

--
William M. Miller, w...@fastdial.net
Vignette Corporation (www.vignette.com)

Sent via Deja.com http://www.deja.com/
Before you buy.

---

0 new messages