简体   繁体   中英

Scope of parameters in a complex function definition

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, ie 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?

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.

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;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM