Reputation: 31
Consider the following obscure definition of a function returning a pointer to an array of char
s:
char (*func(int var))[sizeof var]
{
return 0;
}
Is it valid?
The questionable part is the use of the identifier var
in the sizeof
expression. At least according to GCC 4.9.2, var
is not visible in the sizeof
expression. (Note that if var
in the sizeof expression is replaced with, say, 42
, the code is valid and this question becomes uninteresting.)
However, in the C11 specification draft n1570 (relevant parts are the same in C99, though possibly with different subclause numbering), subclause 6.2.1 discusses the scopes of identifiers, and contains the following sentences that are relevant for this case:
6.2.1p4 contains:
If the declarator or type specifier that declares the identifier appears inside a block or within the list of parameter declarations in a function definition, the identifier has block scope, which terminates at the end of the associated block.
6.2.1p7 contains (bolding mine):
Structure, union, and enumeration tags have scope that begins just after the appearance of the tag in a type specifier that declares the tag. Each enumeration constant has scope that begins just after the appearance of its defining enumerator in an enumerator list. Any other identifier has scope that begins just after the completion of its declarator.
Clearly, the declarator for var
appears inside the list of parameter declarations in the definition of a function. So according to 6.2.1p4 its scope ends at the end of the function body ("associated block"). Also, var
clearly corresponds to "any other identifier" mentioned in 6.2.1p7, so its scope begins just after the completion of its declarator, i.e. at the end of the parameter list.
It seems to me that the specification says nothing else relevant about the scope of var
. Given that the specification doesn't say otherwise, the obvious (to me, anyway) interpretation of the "beginning" and "end" of a scope means that the scope spans the entire lexical interval from the beginning to the end. Thus it seems that var
should in fact be visible in the sizeof
expression.
Is there something in the specification that I haven't accounted for? Is the concept of the scope of an identifier meant to be interpreted in some other way than "the uninterrupted lexical interval from the beginning of the scope to the end of the scope"? If so, how is this apparent in the specification?
Upvotes: 3
Views: 153
Reputation: 311088
The return type of a function is defined in the block scope or file scope where the function itself is declared. It does not belong to the outer-most block scope of the function definition. In this scope (where the function is declared) parameters of the function are not yet declared.
You can consider the function definition like
return type: char ( * )[sizeof var] // Oops..What is var?!
{
// function block scope including its parameters declarations;
int var;
}
Upvotes: 1
Reputation: 78963
The [sizeof var]
part is simply not part of the block, nor of the declaration list, but of the return type. So the only identifiers that are visible there are those with file scope.
Upvotes: 2