C syntax ambiguity

G

Gand Alf

Hello

Imagine the following code occurring at Function Scope:

{
f();
}

Now there might be two valid programmer intentions here.

Either he is declaring f to be a function returning int and taking an
unspecified number of arguments.

Or, he is calling a function f with no arguments and discarding it's
return value.

Most compilers seem to prefer the second interpretation. However, as it
would be possible to call the function unambiguously by dereferencing:
(*f)();
wouldn't it be preferable for the first interpretation to be made?

[Rgds]
 
T

Tom St Denis

Hello

Imagine the following code occurring at Function Scope:

{
  f();

}

Now there might be two valid programmer intentions here.

Either he is declaring f to be a function returning int and taking an
unspecified number of arguments.

Is that interpretation even valid in C90 or 99? At the very least
he'd have to write

f(void);

If he meant to declare a function and not call it.

When I see a lonely f(); I see a function call.

Tom
 
B

Ben Pfaff

Gand Alf said:
{
f();
}

Now there might be two valid programmer intentions here.

Either he is declaring f to be a function returning int and taking an
unspecified number of arguments.

Nope. In C89, a declaration has to have a storage class
specifier, a type specifier, or a type qualifier. Otherwise it
doesn't fit the syntax of a declaration and so it can't be
interpreted as one.
 
K

Keith Thompson

Gand Alf said:
Imagine the following code occurring at Function Scope:

{
f();
}

Now there might be two valid programmer intentions here.

Either he is declaring f to be a function returning int and taking an
unspecified number of arguments.

Or, he is calling a function f with no arguments and discarding it's
return value.

Most compilers seem to prefer the second interpretation. However, as it
would be possible to call the function unambiguously by dereferencing:
(*f)();
wouldn't it be preferable for the first interpretation to be made?

In C99, f(); is unambiguously a function call, since implicit int was
removed from the language.

In C90, at least gcc consistently treats it as a function call, and
complains if there's a declaration following it. I've tried and failed
to find wording in the C90 standard that says it can't be a function
declarator. Anyone else?
 
K

Keith Thompson

Ben Pfaff said:
Nope. In C89, a declaration has to have a storage class
specifier, a type specifier, or a type qualifier. Otherwise it
doesn't fit the syntax of a declaration and so it can't be
interpreted as one.

That makes sense, but where is that rule stated? I can't find it
in the C90 standard.
 
B

Ben Bacarisse

Keith Thompson said:
That makes sense, but where is that rule stated? I can't find it
in the C90 standard.

I don't have an authoritative copy, but the text file widely available
online has this syntax:

declaration:
declaration-specifiers init-declarator-list<opt> ;

declaration-specifiers:
storage-class-specifier declaration-specifiers<opt>
type-specifier declaration-specifiers<opt>
type-qualifier declaration-specifiers<opt>

which is exactly what Ben Pfaff said. None of storage-class-specifier,
type-specifier or type-qualifier can be empty. Is this the syntax you
have in your C90 copy?
 
B

Ben Bacarisse

In C90, at least gcc consistently treats it as a function call, and
complains if there's a declaration following it. I've tried and failed
to find wording in the C90 standard that says it can't be a function
declarator. Anyone else?

Not wording as such but it's in the syntax. See my other post.

For what it's worth, the fact that a declaration must start with a
keyword or a typedef name was there in K&R C and is still there in C99.
I don't have a certified copy of C90, but it seems as odd thing to have
altered (and the altered back).
 
B

Ben Pfaff

Keith Thompson said:
That makes sense, but where is that rule stated? I can't find it
in the C90 standard.

It's stated as part of the context-free grammar for "declaration"
in the standard.
 
K

Keith Thompson

Ben Bacarisse said:
I don't have an authoritative copy, but the text file widely available
online has this syntax:

declaration:
declaration-specifiers init-declarator-list<opt> ;

declaration-specifiers:
storage-class-specifier declaration-specifiers<opt>
type-specifier declaration-specifiers<opt>
type-qualifier declaration-specifiers<opt>

which is exactly what Ben Pfaff said. None of storage-class-specifier,
type-specifier or type-qualifier can be empty. Is this the syntax you
have in your C90 copy?

Yes, that's it; I just managed to miss it.

Incidentally, C99 has:

declaration-specifiers:
storage-class-specifier declaration-specifiers<opt>
type-specifier declaration-specifiers<opt>
type-qualifier declaration-specifiers<opt>
function-specifier declaration-specifiers<opt>

The only function-specifier is "inline".

Which means that this:

inline;

doesn't violate the grammar for a declaration -- but it does violate the
constraint in 6.7p2:

A declaration shall declare at least a declarator (other than
the parameters of a function or the members of a structure or
union), a tag, or the members of an enumeration.
 
B

Ben Bacarisse

Keith Thompson said:
Incidentally, C99 has:

declaration-specifiers:
storage-class-specifier declaration-specifiers<opt>
type-specifier declaration-specifiers<opt>
type-qualifier declaration-specifiers<opt>
function-specifier declaration-specifiers<opt>

The only function-specifier is "inline".

Which means that this:

inline;

doesn't violate the grammar for a declaration -- but it does violate the
constraint in 6.7p2:

A declaration shall declare at least a declarator (other than
the parameters of a function or the members of a structure or
union), a tag, or the members of an enumeration.

I'm not sure why you singled out "inline" or C99. The syntax for a
declaration is

declaration-specifiers init-declarator-list<opt> ;

so all of

int;
const;
extern;

satisfy the syntax but violate the constraint.
 
T

Tim Rentsch

Ben Bacarisse said:
Not wording as such but it's in the syntax. See my other post.

For what it's worth, the fact that a declaration must start with a
keyword or a typedef name was there in K&R C and is still there in C99.
I don't have a certified copy of C90, but it seems as odd thing to have
altered (and the altered back).

Probably there was confusion with function _definitions_, which
did not require any declaration-specifiers (in K&R C and C90),
and were implicitly 'int' if not declared.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,952
Messages
2,570,111
Members
46,695
Latest member
Juliane58C

Latest Threads

Top